changeset 56475:07780e111946 stats-before-this-super

Automatic merge with default
author mcimadamore
date Thu, 30 May 2019 19:49:55 +0200
parents 9f956d52c1d1 ad4285992012
children 93dac461abf5
files src/hotspot/share/Xusage.txt src/hotspot/share/gc/shenandoah/shenandoahHeapLock.hpp src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties test/fmw/gtest/CHANGES test/fmw/gtest/CONTRIBUTORS test/fmw/gtest/LICENSE test/fmw/gtest/README.md test/fmw/gtest/include/gtest/gtest-death-test.h test/fmw/gtest/include/gtest/gtest-message.h test/fmw/gtest/include/gtest/gtest-param-test.h test/fmw/gtest/include/gtest/gtest-param-test.h.pump test/fmw/gtest/include/gtest/gtest-printers.h test/fmw/gtest/include/gtest/gtest-spi.h test/fmw/gtest/include/gtest/gtest-test-part.h test/fmw/gtest/include/gtest/gtest-typed-test.h test/fmw/gtest/include/gtest/gtest.h test/fmw/gtest/include/gtest/gtest_pred_impl.h test/fmw/gtest/include/gtest/gtest_prod.h test/fmw/gtest/include/gtest/internal/custom/README.md test/fmw/gtest/include/gtest/internal/custom/gtest-port.h test/fmw/gtest/include/gtest/internal/custom/gtest-printers.h test/fmw/gtest/include/gtest/internal/custom/gtest.h test/fmw/gtest/include/gtest/internal/gtest-death-test-internal.h test/fmw/gtest/include/gtest/internal/gtest-filepath.h test/fmw/gtest/include/gtest/internal/gtest-internal.h test/fmw/gtest/include/gtest/internal/gtest-linked_ptr.h test/fmw/gtest/include/gtest/internal/gtest-param-util-generated.h test/fmw/gtest/include/gtest/internal/gtest-param-util-generated.h.pump test/fmw/gtest/include/gtest/internal/gtest-param-util.h test/fmw/gtest/include/gtest/internal/gtest-port-arch.h test/fmw/gtest/include/gtest/internal/gtest-port.h test/fmw/gtest/include/gtest/internal/gtest-string.h test/fmw/gtest/include/gtest/internal/gtest-tuple.h test/fmw/gtest/include/gtest/internal/gtest-tuple.h.pump test/fmw/gtest/include/gtest/internal/gtest-type-util.h test/fmw/gtest/include/gtest/internal/gtest-type-util.h.pump test/fmw/gtest/src/gtest-all.cc test/fmw/gtest/src/gtest-death-test.cc test/fmw/gtest/src/gtest-filepath.cc test/fmw/gtest/src/gtest-internal-inl.h test/fmw/gtest/src/gtest-port.cc test/fmw/gtest/src/gtest-printers.cc test/fmw/gtest/src/gtest-test-part.cc test/fmw/gtest/src/gtest-typed-test.cc test/fmw/gtest/src/gtest.cc test/fmw/gtest/src/gtest_main.cc
diffstat 393 files changed, 65702 insertions(+), 38549 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu May 23 22:12:31 2019 +0200
+++ b/.hgtags	Thu May 30 19:49:55 2019 +0200
@@ -560,3 +560,4 @@
 6ccc7cd7931e34129f6b7e04988fc9a63958dde0 jdk-13+20
 f2f11d7f7f4e7128f8aba6ffa576cfa76fbf7d1a jdk-13+21
 181986c5476468bc2dd4532af49599003ee8af37 jdk-13+22
+b034d2dee5fc93d42a81b65e58ce3f91e42586ff jdk-13+23
--- a/make/Docs.gmk	Thu May 23 22:12:31 2019 +0200
+++ b/make/Docs.gmk	Thu May 30 19:49:55 2019 +0200
@@ -586,6 +586,7 @@
             CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \
             OPTIONS := -A $($m_$f_BOTTOM_FILE), \
             EXTRA_DEPS := $($m_$f_BOTTOM_FILE), \
+            POST_PROCESS := $(TOOL_FIXUPPANDOC), \
         )) \
         $(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
       ) \
@@ -616,6 +617,7 @@
             CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \
             REPLACEMENTS := @@VERSION_SHORT@@ => $(VERSION_SHORT), \
             OPTIONS := -A $(SPECS_BOTTOM_FILE_1), \
+            POST_PROCESS := $(TOOL_FIXUPPANDOC), \
             EXTRA_DEPS := $(PANDOC_HTML_MANPAGE_FILTER) \
                 $(PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT) \
                 $(SPECS_BOTTOM_FILE_1), \
--- a/make/Main.gmk	Thu May 23 22:12:31 2019 +0200
+++ b/make/Main.gmk	Thu May 30 19:49:55 2019 +0200
@@ -869,7 +869,7 @@
   JVM_DOCS_TARGETS ?= hotspot-$(JVM_VARIANT_MAIN)-gensrc
 
   # The gensrc steps for hotspot and jdk.jdi create html spec files.
-  docs-jdk-specs: $(JVM_DOCS_TARGETS) jdk.jdi-gensrc \
+  docs-jdk-specs: buildtools-jdk $(JVM_DOCS_TARGETS) jdk.jdi-gensrc \
       docs-jdk-index
 
   docs-zip: docs-jdk
--- a/make/RunTests.gmk	Thu May 23 22:12:31 2019 +0200
+++ b/make/RunTests.gmk	Thu May 30 19:49:55 2019 +0200
@@ -1199,7 +1199,7 @@
     JCOV_REPORT_TITLE += Code filters: $(JCOV_FILTERS)<br>
   endif
   JCOV_REPORT_TITLE += Tests: $(TEST)
-	
+
   jcov-gen-report: jcov-stop-grabber
 	$(call LogWarn, Generating JCov report ...)
 	$(JAVA) -Xmx4g -jar $(JCOV_HOME)/lib/jcov.jar RepGen -sourcepath \
--- a/make/RunTestsPrebuilt.gmk	Thu May 23 22:12:31 2019 +0200
+++ b/make/RunTestsPrebuilt.gmk	Thu May 30 19:49:55 2019 +0200
@@ -337,6 +337,10 @@
 default: all
 
 run-test-prebuilt:
+        # Need to make sure the failure logs output dir exists since
+        # ExecuteWithLog is called in RunTests.gmk. The PrepareFailureLogs macro
+        # is unfortunately not available at this point.
+	$(call MakeDir, $(MAKESUPPORT_OUTPUTDIR)/failure-logs)
 	@$(RM) -f $(MAKESUPPORT_OUTPUTDIR)/exit-with-error
         # The lazy initialization of the cache file in FindTests.gmk does not
         # always work with RunTests.gmk. To guarantee that the jtreg test groups
--- a/make/ToolsJdk.gmk	Thu May 23 22:12:31 2019 +0200
+++ b/make/ToolsJdk.gmk	Thu May 30 19:49:55 2019 +0200
@@ -117,6 +117,9 @@
 TOOL_PUBLICSUFFIXLIST = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
     build.tools.publicsuffixlist.GeneratePublicSuffixList
 
+TOOL_FIXUPPANDOC = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
+    build.tools.fixuppandoc.Main
+
 ##########################################################################################
 
 # Executable javascript filter for man page generation using pandoc.
--- a/make/hotspot/gensrc/GenerateSources.gmk	Thu May 23 22:12:31 2019 +0200
+++ b/make/hotspot/gensrc/GenerateSources.gmk	Thu May 30 19:49:55 2019 +0200
@@ -46,15 +46,6 @@
 # While technically the rules below are "gendata" which can be done in parallel
 # with native compilation, let's keep it here for simplicity.
 
-# The Xusage.txt file needs to have platform specific path separator
-$(eval $(call SetupTextFileProcessing, CREATE_XUSAGE, \
-    SOURCE_FILES := $(TOPDIR)/src/hotspot/share/Xusage.txt, \
-    OUTPUT_FILE := $(JVM_LIB_OUTPUTDIR)/Xusage.txt, \
-    REPLACEMENTS := separated by ;> => separated by $(PATH_SEP)> ; , \
-))
-
-TARGETS += $(CREATE_XUSAGE)
-
 # Setup the hotspot launcher script for developer use
 $(eval $(call SetupTextFileProcessing, CREATE_HOTSPOT_LAUNCHER, \
     SOURCE_FILES := $(TOPDIR)/make/hotspot/hotspot.script, \
--- a/make/hotspot/lib/CompileGtest.gmk	Thu May 23 22:12:31 2019 +0200
+++ b/make/hotspot/lib/CompileGtest.gmk	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -64,11 +64,16 @@
     EXCLUDES := $(JVM_EXCLUDES), \
     EXCLUDE_FILES := gtestLauncher.cpp, \
     EXCLUDE_PATTERNS := $(JVM_EXCLUDE_PATTERNS), \
-    EXTRA_FILES := $(GTEST_FRAMEWORK_SRC)/src/gtest-all.cc, \
+    EXTRA_FILES := \
+        $(GTEST_FRAMEWORK_SRC)/googletest/src/gtest-all.cc \
+        $(GTEST_FRAMEWORK_SRC)/googlemock/src/gmock-all.cc, \
     EXTRA_OBJECT_FILES := $(filter-out %/operator_new$(OBJ_SUFFIX), \
         $(BUILD_LIBJVM_ALL_OBJS)), \
-    CFLAGS := $(JVM_CFLAGS) -I$(GTEST_FRAMEWORK_SRC) \
-        -I$(GTEST_FRAMEWORK_SRC)/include \
+    CFLAGS := $(JVM_CFLAGS) \
+        -I$(GTEST_FRAMEWORK_SRC)/googletest \
+        -I$(GTEST_FRAMEWORK_SRC)/googletest/include \
+        -I$(GTEST_FRAMEWORK_SRC)/googlemock \
+        -I$(GTEST_FRAMEWORK_SRC)/googlemock/include \
         $(addprefix -I,$(GTEST_TEST_SRC)), \
     CFLAGS_windows := -EHsc, \
     CFLAGS_solaris := -DGTEST_HAS_EXCEPTIONS=0 -library=stlport4, \
@@ -90,7 +95,7 @@
     ZIP_EXTERNAL_DEBUG_SYMBOLS := false, \
     STRIP_SYMBOLS := false, \
     PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \
-    PRECOMPILED_HEADER_EXCLUDE := gtest-all.cc gtestMain.cpp, \
+    PRECOMPILED_HEADER_EXCLUDE := gtest-all.cc gmock-all.cc gtestMain.cpp, \
     DEFINE_THIS_FILE := false, \
 ))
 
@@ -105,8 +110,11 @@
     OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
     EXTRA_FILES := $(GTEST_LAUNCHER_SRC), \
     OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/launcher-objs, \
-    CFLAGS := $(JVM_CFLAGS) -I$(GTEST_FRAMEWORK_SRC) \
-        -I$(GTEST_FRAMEWORK_SRC)/include, \
+    CFLAGS := $(JVM_CFLAGS) \
+        -I$(GTEST_FRAMEWORK_SRC)/googletest \
+        -I$(GTEST_FRAMEWORK_SRC)/googletest/include \
+        -I$(GTEST_FRAMEWORK_SRC)/googlemock \
+        -I$(GTEST_FRAMEWORK_SRC)/googlemock/include, \
     LDFLAGS := $(LDFLAGS_JDKEXE), \
     LDFLAGS_unix := -L$(JVM_OUTPUTDIR)/gtest $(call SET_SHARED_LIBRARY_ORIGIN), \
     LDFLAGS_solaris := -library=stlport4, \
--- a/make/hotspot/lib/JvmDtraceObjects.gmk	Thu May 23 22:12:31 2019 +0200
+++ b/make/hotspot/lib/JvmDtraceObjects.gmk	Thu May 30 19:49:55 2019 +0200
@@ -51,7 +51,9 @@
         hs_private.d \
     )
 
-    $(JVM_OUTPUTDIR)/objs/dtrace.d: $(DTRACE_SOURCE_FILES)
+    # *.d in the objs dir is used for generated make dependency files, so use
+    # *.dt for dtrace files to avoid clashes.
+    $(JVM_OUTPUTDIR)/objs/dtrace.dt: $(DTRACE_SOURCE_FILES)
 	$(call LogInfo, Generating $(@F))
 	$(call MakeDir, $(@D))
 	$(CAT) $^ > $@
@@ -94,13 +96,13 @@
 
     # Make sure we run our selected compiler for preprocessing instead of letting
     # the dtrace tool pick it on it's own.
-    $(DTRACE_OBJ): $(JVM_OUTPUTDIR)/objs/dtrace.d $(DTRACE_INSTRUMENTED_OBJS)
+    $(DTRACE_OBJ): $(JVM_OUTPUTDIR)/objs/dtrace.dt $(DTRACE_INSTRUMENTED_OBJS)
 	$(call LogInfo, Generating $(@F) from $(<F) and object files)
 	$(call MakeDir, $(DTRACE_SUPPORT_DIR))
-	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, \
-	    ($(CPP) $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d))
+	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).dt, \
+	    ($(CPP) $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).dt))
 	$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -xlazyload -o $@ \
-	    -s $(DTRACE_SUPPORT_DIR)/$(@F).d $(sort $(DTRACE_INSTRUMENTED_OBJS)))
+	    -s $(DTRACE_SUPPORT_DIR)/$(@F).dt $(sort $(DTRACE_INSTRUMENTED_OBJS)))
 
     ############################################################################
     # Generate DTRACE_JHELPER_OBJ which is linked with libjvm.so.
@@ -126,11 +128,11 @@
     $(DTRACE_JHELPER_OBJ): $(JHELPER_DTRACE_SRC) $(JVM_OFFSETS_INDEX_H)
 	$(call LogInfo, Running dtrace for $(<F))
 	$(call MakeDir, $(DTRACE_SUPPORT_DIR))
-	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, \
+	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).dt, \
 	    ($(CPP) $(DTRACE_CPP_FLAGS) -I$(DTRACE_GENSRC_DIR) $^ \
-	    > $(DTRACE_SUPPORT_DIR)/$(@F).d))
+	    > $(DTRACE_SUPPORT_DIR)/$(@F).dt))
 	$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -o $@ \
-	    -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
+	    -s $(DTRACE_SUPPORT_DIR)/$(@F).dt)
         ifeq ($(call isTargetCpuArch, sparc), true)
 	  $(call ExecuteWithLog, $@.elfedit, $(ELFEDIT) $(call GetElfeditCommands) $@)
         endif
--- a/make/scripts/compare.sh	Thu May 23 22:12:31 2019 +0200
+++ b/make/scripts/compare.sh	Thu May 30 19:49:55 2019 +0200
@@ -820,6 +820,9 @@
             BIN_MSG="($BIN_MSG)"
             DIFF_BIN=
         fi
+    else
+        BIN_MSG=
+        DIFF_BIN=
     fi
 
     if [ -n "$STAT" ]; then
@@ -1571,15 +1574,12 @@
     fi
     if [ -n "$THIS_TEST" ] && [ -n "$OTHER_TEST" ]; then
         echo -n "Test "
-        # Test native libs are never stripped so will not compare well.
-        SKIP_BIN_DIFF="true"
-        ACCEPTED_SMALL_SIZE_DIFF_bak="$ACCEPTED_SMALL_SIZE_DIFF"
-        if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
-            ACCEPTED_SMALL_SIZE_DIFF="true"
+        STRIP_ALL_bak="$STRIP_ALL"
+        if [ "$STRIP_TESTS_BEFORE_COMPARE" = "true" ]; then
+          STRIP_ALL="true"
         fi
         compare_all_libs $THIS_TEST $OTHER_TEST $COMPARE_ROOT/test
-        SKIP_BIN_DIFF="false"
-        ACCEPTED_SMALL_SIZE_DIFF="$ACCEPTED_SMALL_SIZE_DIFF_bak"
+        STRIP_ALL="$STRIP_ALL_bak"
     fi
     if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
         compare_all_libs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
@@ -1593,10 +1593,12 @@
     fi
     if [ -n "$THIS_TEST" ] && [ -n "$OTHER_TEST" ]; then
         echo -n "Test "
-        # Test native executables are never stripped so will not compare well.
-        SKIP_BIN_DIFF="true"
+        STRIP_ALL_bak="$STRIP_ALL"
+        if [ "$STRIP_TESTS_BEFORE_COMPARE" = "true" ]; then
+          STRIP_ALL="true"
+        fi
         compare_all_execs $THIS_TEST $OTHER_TEST $COMPARE_ROOT/test
-        SKIP_BIN_DIFF="false"
+        STRIP_ALL="$STRIP_ALL_bak"
     fi
     if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
         compare_all_execs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
--- a/make/scripts/compare_exceptions.sh.incl	Thu May 23 22:12:31 2019 +0200
+++ b/make/scripts/compare_exceptions.sh.incl	Thu May 30 19:49:55 2019 +0200
@@ -40,6 +40,9 @@
       ./lib/server/libjvm.so
       ./hotspot/gtest/server/libjvm.so
       "
+  STRIP_BEFORE_COMPARE="
+      ./hotspot/gtest/server/libjvm.so
+      "
 elif [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
   SKIP_BIN_DIFF="true"
   SKIP_FULLDUMP_DIFF="true"
@@ -56,6 +59,7 @@
       ./lib/libfontmanager.so
       ./lib/libsaproc.so
   "
+  STRIP_TESTS_BEFORE_COMPARE="true"
 elif [ "$OPENJDK_TARGET_OS" = "windows" ]; then
   SKIP_BIN_DIFF="true"
   SKIP_FULLDUMP_DIFF="true"
@@ -72,4 +76,5 @@
       ./lib/server/libjvm.dylib
       ./hotspot/gtest/server/libjvm.dylib
       "
+  STRIP_TESTS_BEFORE_COMPARE="true"
 fi
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Thu May 30 19:49:55 2019 +0200
@@ -1491,6 +1491,25 @@
   INSN(eorw, 0, 0b10, 0);
   INSN(andsw, 0, 0b11, 0);
 
+#undef INSN
+
+#define INSN(NAME, size, op, N)                                         \
+  void NAME(Register Rd, Register Rn, Register Rm,                      \
+            enum shift_kind kind = LSL, unsigned shift = 0) {           \
+    starti;                                                             \
+    f(N, 21);                                                           \
+    zrf(Rm, 16), zrf(Rn, 5), zrf(Rd, 0);                                \
+    op_shifted_reg(0b01010, kind, shift, size, op);                     \
+  }                                                                     \
+                                                                        \
+  /* These instructions have no immediate form. Provide an overload so  \
+     that if anyone does try to use an immediate operand -- this has    \
+     happened! -- we'll get a compile-time error. */                    \
+  void NAME(Register Rd, Register Rn, unsigned imm,                     \
+            enum shift_kind kind = LSL, unsigned shift = 0) {           \
+    assert(false, " can't be used with immediate operand");             \
+  }
+
   INSN(bic, 1, 0b00, 1);
   INSN(orn, 1, 0b01, 1);
   INSN(eon, 1, 0b10, 1);
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Thu May 30 19:49:55 2019 +0200
@@ -316,6 +316,9 @@
   return start_offset;
 }
 
+void LIR_Assembler::clinit_barrier(ciMethod* method) {
+  ShouldNotReachHere(); // not implemented
+}
 
 void LIR_Assembler::jobject2reg(jobject o, Register reg) {
   if (o == NULL) {
@@ -2268,7 +2271,7 @@
     __ ldr(src,              Address(sp, 4*BytesPerWord));
 
     // r0 is -1^K where K == partial copied count
-    __ eonw(rscratch1, r0, 0);
+    __ eonw(rscratch1, r0, zr);
     // adjust length down and src/end pos up by partial copied count
     __ subw(length, length, rscratch1);
     __ addw(src_pos, src_pos, rscratch1);
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp	Thu May 30 19:49:55 2019 +0200
@@ -211,18 +211,46 @@
   __ bind(done);
 }
 
-void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst) {
+void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp) {
   assert(ShenandoahLoadRefBarrier || ShenandoahCASBarrier, "Should be enabled");
   Label is_null;
   __ cbz(dst, is_null);
-  resolve_forward_pointer_not_null(masm, dst);
+  resolve_forward_pointer_not_null(masm, dst, tmp);
   __ bind(is_null);
 }
 
-// IMPORTANT: This must preserve all registers, even rscratch1 and rscratch2.
-void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst) {
+// IMPORTANT: This must preserve all registers, even rscratch1 and rscratch2, except those explicitely
+// passed in.
+void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) {
   assert(ShenandoahLoadRefBarrier || ShenandoahCASBarrier, "Should be enabled");
-  __ ldr(dst, Address(dst, ShenandoahForwarding::byte_offset()));
+  // The below loads the mark word, checks if the lowest two bits are
+  // set, and if so, clear the lowest two bits and copy the result
+  // to dst. Otherwise it leaves dst alone.
+  // Implementing this is surprisingly awkward. I do it here by:
+  // - Inverting the mark word
+  // - Test lowest two bits == 0
+  // - If so, set the lowest two bits
+  // - Invert the result back, and copy to dst
+
+  bool borrow_reg = (tmp == noreg);
+  if (borrow_reg) {
+    // No free registers available. Make one useful.
+    tmp = rscratch1;
+    __ push(RegSet::of(tmp), sp);
+  }
+
+  Label done;
+  __ ldr(tmp, Address(dst, oopDesc::mark_offset_in_bytes()));
+  __ eon(tmp, tmp, zr);
+  __ ands(zr, tmp, markOopDesc::lock_mask_in_place);
+  __ br(Assembler::NE, done);
+  __ orr(tmp, tmp, markOopDesc::marked_value);
+  __ eon(dst, tmp, zr);
+  __ bind(done);
+
+  if (borrow_reg) {
+    __ pop(RegSet::of(tmp), sp);
+  }
 }
 
 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Register tmp) {
@@ -343,40 +371,6 @@
 
 }
 
-void ShenandoahBarrierSetAssembler::tlab_allocate(MacroAssembler* masm, Register obj,
-                                                  Register var_size_in_bytes,
-                                                  int con_size_in_bytes,
-                                                  Register t1,
-                                                  Register t2,
-                                                  Label& slow_case) {
-
-  assert_different_registers(obj, t2);
-  assert_different_registers(obj, var_size_in_bytes);
-  Register end = t2;
-
-  __ ldr(obj, Address(rthread, JavaThread::tlab_top_offset()));
-  if (var_size_in_bytes == noreg) {
-    __ lea(end, Address(obj, (int) (con_size_in_bytes + ShenandoahForwarding::byte_size())));
-  } else {
-    __ add(var_size_in_bytes, var_size_in_bytes, ShenandoahForwarding::byte_size());
-    __ lea(end, Address(obj, var_size_in_bytes));
-  }
-  __ ldr(rscratch1, Address(rthread, JavaThread::tlab_end_offset()));
-  __ cmp(end, rscratch1);
-  __ br(Assembler::HI, slow_case);
-
-  // update the tlab top pointer
-  __ str(end, Address(rthread, JavaThread::tlab_top_offset()));
-
-  __ add(obj, obj, ShenandoahForwarding::byte_size());
-  __ str(obj, Address(obj, ShenandoahForwarding::byte_offset()));
-
-  // recover var_size_in_bytes if necessary
-  if (var_size_in_bytes == end) {
-    __ sub(var_size_in_bytes, var_size_in_bytes, obj);
-  }
-}
-
 void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val,
                                                 bool acquire, bool release, bool weak, bool is_cae,
                                                 Register result) {
@@ -570,7 +564,7 @@
   __ bind(work);
 
   __ mov(rscratch2, r0);
-  resolve_forward_pointer_not_null(cgen->assembler(), r0);
+  resolve_forward_pointer_not_null(cgen->assembler(), r0, rscratch1);
   __ cmp(rscratch2, r0);
   __ br(Assembler::NE, done);
 
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp	Thu May 30 19:49:55 2019 +0200
@@ -54,8 +54,8 @@
                                     bool tosca_live,
                                     bool expand_call);
 
-  void resolve_forward_pointer(MacroAssembler* masm, Register dst);
-  void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst);
+  void resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp = noreg);
+  void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg);
   void load_reference_barrier(MacroAssembler* masm, Register dst, Register tmp);
   void load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Register tmp);
 
@@ -80,13 +80,6 @@
                        Register dst, Address src, Register tmp1, Register tmp_thread);
   virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                         Address dst, Register val, Register tmp1, Register tmp2);
-  virtual void tlab_allocate(MacroAssembler* masm, Register obj,
-                             Register var_size_in_bytes,
-                             int con_size_in_bytes,
-                             Register t1,
-                             Register t2,
-                             Label& slow_case);
-
   void cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val,
                    bool acquire, bool release, bool weak, bool is_cae, Register result);
 
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Thu May 30 19:49:55 2019 +0200
@@ -129,8 +129,11 @@
 
   int dcache_line = VM_Version::dcache_line_size();
 
+  // Limit AllocatePrefetchDistance so that it does not exceed the
+  // constraint in AllocatePrefetchDistanceConstraintFunc.
   if (FLAG_IS_DEFAULT(AllocatePrefetchDistance))
-    FLAG_SET_DEFAULT(AllocatePrefetchDistance, 3*dcache_line);
+    FLAG_SET_DEFAULT(AllocatePrefetchDistance, MIN2(512, 3*dcache_line));
+
   if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize))
     FLAG_SET_DEFAULT(AllocatePrefetchStepSize, dcache_line);
   if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes))
--- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp	Thu May 30 19:49:55 2019 +0200
@@ -191,6 +191,9 @@
   return offset;
 }
 
+void LIR_Assembler::clinit_barrier(ciMethod* method) {
+  ShouldNotReachHere(); // not implemented
+}
 
 void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) {
   jobject o = (jobject)Universe::non_oop_word();
--- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp	Thu May 30 19:49:55 2019 +0200
@@ -79,6 +79,9 @@
   return offset;
 }
 
+void LIR_Assembler::clinit_barrier(ciMethod* method) {
+  ShouldNotReachHere(); // not implemented
+}
 
 void LIR_Assembler::osr_entry() {
   // On-stack-replacement entry sequence:
--- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp	Thu May 30 19:49:55 2019 +0200
@@ -81,6 +81,10 @@
   return offset;
 }
 
+void LIR_Assembler::clinit_barrier(ciMethod* method) {
+  ShouldNotReachHere(); // not implemented
+}
+
 void LIR_Assembler::osr_entry() {
   // On-stack-replacement entry sequence (interpreter frame layout described in interpreter_sparc.cpp):
   //
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Thu May 30 19:49:55 2019 +0200
@@ -172,6 +172,9 @@
   return offset;
 }
 
+void LIR_Assembler::clinit_barrier(ciMethod* method) {
+  ShouldNotReachHere(); // not implemented
+}
 
 void LIR_Assembler::osr_entry() {
   // On-stack-replacement entry sequence (interpreter frame layout described in interpreter_sparc.cpp):
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp	Thu May 30 19:49:55 2019 +0200
@@ -359,6 +359,23 @@
   return offset;
 }
 
+void LIR_Assembler::clinit_barrier(ciMethod* method) {
+  assert(VM_Version::supports_fast_class_init_checks(), "sanity");
+  assert(method->holder()->is_being_initialized() || method->holder()->is_initialized(),
+         "initialization should have been started");
+
+  Label L_skip_barrier;
+  Register klass = rscratch1;
+  Register thread = LP64_ONLY( r15_thread ) NOT_LP64( noreg );
+  assert(thread != noreg, "x86_32 not implemented");
+
+  __ mov_metadata(klass, method->holder()->constant_encoding());
+  __ clinit_barrier(klass, thread, &L_skip_barrier /*L_fast_path*/);
+
+  __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+
+  __ bind(L_skip_barrier);
+}
 
 void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) {
   jobject o = NULL;
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp	Thu May 30 19:49:55 2019 +0200
@@ -317,18 +317,46 @@
   __ bind(done);
 }
 
-void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst) {
+void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp) {
   assert(ShenandoahCASBarrier, "should be enabled");
   Label is_null;
   __ testptr(dst, dst);
   __ jcc(Assembler::zero, is_null);
-  resolve_forward_pointer_not_null(masm, dst);
+  resolve_forward_pointer_not_null(masm, dst, tmp);
   __ bind(is_null);
 }
 
-void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst) {
+void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) {
   assert(ShenandoahCASBarrier || ShenandoahLoadRefBarrier, "should be enabled");
-  __ movptr(dst, Address(dst, ShenandoahForwarding::byte_offset()));
+  // The below loads the mark word, checks if the lowest two bits are
+  // set, and if so, clear the lowest two bits and copy the result
+  // to dst. Otherwise it leaves dst alone.
+  // Implementing this is surprisingly awkward. I do it here by:
+  // - Inverting the mark word
+  // - Test lowest two bits == 0
+  // - If so, set the lowest two bits
+  // - Invert the result back, and copy to dst
+
+  bool borrow_reg = (tmp == noreg);
+  if (borrow_reg) {
+    // No free registers available. Make one useful.
+    tmp = rscratch1;
+    __ push(tmp);
+  }
+
+  Label done;
+  __ movptr(tmp, Address(dst, oopDesc::mark_offset_in_bytes()));
+  __ notptr(tmp);
+  __ testb(tmp, markOopDesc::marked_value);
+  __ jccb(Assembler::notZero, done);
+  __ orptr(tmp, markOopDesc::marked_value);
+  __ notptr(tmp);
+  __ mov(dst, tmp);
+  __ bind(done);
+
+  if (borrow_reg) {
+    __ pop(tmp);
+  }
 }
 
 
@@ -338,13 +366,7 @@
   Label done;
 
   Address gc_state(r15_thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
-  __ testb(gc_state, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION | ShenandoahHeap::TRAVERSAL);
-  __ jccb(Assembler::zero, done);
-
-  // Heap is unstable, need to perform the resolve even if LRB is inactive
-  resolve_forward_pointer_not_null(masm, dst);
-
-  __ testb(gc_state, ShenandoahHeap::EVACUATION | ShenandoahHeap::TRAVERSAL);
+  __ testb(gc_state, ShenandoahHeap::HAS_FORWARDED);
   __ jccb(Assembler::zero, done);
 
    if (dst != rax) {
@@ -479,55 +501,6 @@
   }
 }
 
-void ShenandoahBarrierSetAssembler::tlab_allocate(MacroAssembler* masm,
-                                                  Register thread, Register obj,
-                                                  Register var_size_in_bytes,
-                                                  int con_size_in_bytes,
-                                                  Register t1, Register t2,
-                                                  Label& slow_case) {
-  assert_different_registers(obj, t1, t2);
-  assert_different_registers(obj, var_size_in_bytes, t1);
-  Register end = t2;
-  if (!thread->is_valid()) {
-#ifdef _LP64
-    thread = r15_thread;
-#else
-    assert(t1->is_valid(), "need temp reg");
-    thread = t1;
-    __ get_thread(thread);
-#endif
-  }
-
-  __ verify_tlab();
-
-  __ movptr(obj, Address(thread, JavaThread::tlab_top_offset()));
-  if (var_size_in_bytes == noreg) {
-    __ lea(end, Address(obj, con_size_in_bytes + ShenandoahForwarding::byte_size()));
-  } else {
-    __ addptr(var_size_in_bytes, ShenandoahForwarding::byte_size());
-    __ lea(end, Address(obj, var_size_in_bytes, Address::times_1));
-  }
-  __ cmpptr(end, Address(thread, JavaThread::tlab_end_offset()));
-  __ jcc(Assembler::above, slow_case);
-
-  // update the tlab top pointer
-  __ movptr(Address(thread, JavaThread::tlab_top_offset()), end);
-
-  // Initialize brooks pointer
-#ifdef _LP64
-  __ incrementq(obj, ShenandoahForwarding::byte_size());
-#else
-  __ incrementl(obj, ShenandoahForwarding::byte_size());
-#endif
-  __ movptr(Address(obj, ShenandoahForwarding::byte_offset()), obj);
-
-  // recover var_size_in_bytes if necessary
-  if (var_size_in_bytes == end) {
-    __ subptr(var_size_in_bytes, obj);
-  }
-  __ verify_tlab();
-}
-
 // Special Shenandoah CAS implementation that handles false negatives
 // due to concurrent evacuation.
 #ifndef _LP64
@@ -856,7 +829,7 @@
   address start = __ pc();
 
 #ifdef _LP64
-  Label not_done;
+  Label resolve_oop, slow_path;
 
   // We use RDI, which also serves as argument register for slow call.
   // RAX always holds the src object ptr, except after the slow call and
@@ -878,13 +851,31 @@
   // unlive: rdi
   __ testbool(r8);
   // unlive: r8
-  __ jccb(Assembler::notZero, not_done);
+  __ jccb(Assembler::notZero, resolve_oop);
 
   __ pop(r8);
   __ pop(rdi);
   __ ret(0);
 
-  __ bind(not_done);
+  __ bind(resolve_oop);
+
+  __ movptr(r8, Address(rax, oopDesc::mark_offset_in_bytes()));
+  // Test if both lowest bits are set. We trick it by negating the bits
+  // then test for both bits clear.
+  __ notptr(r8);
+  __ testb(r8, markOopDesc::marked_value);
+  __ jccb(Assembler::notZero, slow_path);
+  // Clear both lower bits. It's still inverted, so set them, and then invert back.
+  __ orptr(r8, markOopDesc::marked_value);
+  __ notptr(r8);
+  // At this point, r8 contains the decoded forwarding pointer.
+  __ mov(rax, r8);
+
+  __ pop(r8);
+  __ pop(rdi);
+  __ ret(0);
+
+  __ bind(slow_path);
 
   __ push(rcx);
   __ push(rdx);
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp	Thu May 30 19:49:55 2019 +0200
@@ -55,8 +55,8 @@
                                     bool tosca_live,
                                     bool expand_call);
 
-  void resolve_forward_pointer(MacroAssembler* masm, Register dst);
-  void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst);
+  void resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp = noreg);
+  void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg);
 
   void load_reference_barrier_not_null(MacroAssembler* masm, Register dst);
 
@@ -91,13 +91,6 @@
   virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                         Address dst, Register val, Register tmp1, Register tmp2);
 
-  virtual void tlab_allocate(MacroAssembler* masm,
-                             Register thread, Register obj,
-                             Register var_size_in_bytes,
-                             int con_size_in_bytes,
-                             Register t1, Register t2,
-                             Label& slow_case);
-
   virtual void barrier_stubs_init();
 
 };
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp	Thu May 30 19:49:55 2019 +0200
@@ -487,7 +487,8 @@
                                                                Register tmp,
                                                                int bcp_offset,
                                                                size_t index_size) {
-  assert(cache != tmp, "must use different register");
+  assert_different_registers(cache, tmp);
+
   get_cache_index_at_bcp(tmp, bcp_offset, index_size);
   assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
   // convert from field index to ConstantPoolCacheEntry index
@@ -501,8 +502,9 @@
 }
 
 // Load object from cpool->resolved_references(index)
-void InterpreterMacroAssembler::load_resolved_reference_at_index(
-                                           Register result, Register index, Register tmp) {
+void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result,
+                                                                 Register index,
+                                                                 Register tmp) {
   assert_different_registers(result, index);
 
   get_constant_pool(result);
@@ -516,14 +518,32 @@
 }
 
 // load cpool->resolved_klass_at(index)
-void InterpreterMacroAssembler::load_resolved_klass_at_index(Register cpool,
-                                           Register index, Register klass) {
+void InterpreterMacroAssembler::load_resolved_klass_at_index(Register klass,
+                                                             Register cpool,
+                                                             Register index) {
+  assert_different_registers(cpool, index);
+
   movw(index, Address(cpool, index, Address::times_ptr, sizeof(ConstantPool)));
   Register resolved_klasses = cpool;
   movptr(resolved_klasses, Address(cpool, ConstantPool::resolved_klasses_offset_in_bytes()));
   movptr(klass, Address(resolved_klasses, index, Address::times_ptr, Array<Klass*>::base_offset_in_bytes()));
 }
 
+void InterpreterMacroAssembler::load_resolved_method_at_index(int byte_no,
+                                                              Register method,
+                                                              Register cache,
+                                                              Register index) {
+  assert_different_registers(cache, index);
+
+  const int method_offset = in_bytes(
+    ConstantPoolCache::base_offset() +
+      ((byte_no == TemplateTable::f2_byte)
+       ? ConstantPoolCacheEntry::f2_offset()
+       : ConstantPoolCacheEntry::f1_offset()));
+
+  movptr(method, Address(cache, index, Address::times_ptr, method_offset)); // get f1 Method*
+}
+
 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
 // subtype of super_klass.
 //
--- a/src/hotspot/cpu/x86/interp_masm_x86.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/interp_masm_x86.hpp	Thu May 30 19:49:55 2019 +0200
@@ -124,9 +124,14 @@
   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)
-                                    Register index,  // the constant pool index (corrupted on return)
-                                    Register klass); // contains the Klass on return
+  void load_resolved_klass_at_index(Register klass,  // contains the Klass on return
+                                    Register cpool,  // the constant pool (corrupted on return)
+                                    Register index); // the constant pool index (corrupted on return)
+
+  void load_resolved_method_at_index(int byte_no,
+                                     Register method,
+                                     Register cache,
+                                     Register index);
 
   NOT_LP64(void f2ieee();)        // truncate ftos to 32bits
   NOT_LP64(void d2ieee();)        // truncate dtos to 64bits
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu May 30 19:49:55 2019 +0200
@@ -4603,6 +4603,29 @@
 }
 
 
+void MacroAssembler::clinit_barrier(Register klass, Register thread, Label* L_fast_path, Label* L_slow_path) {
+  assert(L_fast_path != NULL || L_slow_path != NULL, "at least one is required");
+
+  Label L_fallthrough;
+  if (L_fast_path == NULL) {
+    L_fast_path = &L_fallthrough;
+  }
+
+  // Fast path check: class is fully initialized
+  cmpb(Address(klass, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized);
+  jcc(Assembler::equal, *L_fast_path);
+
+  // Fast path check: current thread is initializer thread
+  cmpptr(thread, Address(klass, InstanceKlass::init_thread_offset()));
+  if (L_slow_path != NULL) {
+    jcc(Assembler::notEqual, *L_slow_path);
+  } else {
+    jcc(Assembler::equal, *L_fast_path);
+  }
+
+  bind(L_fallthrough);
+}
+
 void MacroAssembler::cmov32(Condition cc, Register dst, Address src) {
   if (VM_Version::supports_cmov()) {
     cmovl(cc, dst, src);
@@ -5195,20 +5218,22 @@
 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()));
+  load_method_holder(mirror, method);
   movptr(mirror, Address(mirror, mirror_offset));
   resolve_oop_handle(mirror, tmp);
 }
 
 void MacroAssembler::load_method_holder_cld(Register rresult, Register rmethod) {
-  movptr(rresult, Address(rmethod, Method::const_offset()));
-  movptr(rresult, Address(rresult, ConstMethod::constants_offset()));
-  movptr(rresult, Address(rresult, ConstantPool::pool_holder_offset_in_bytes()));
+  load_method_holder(rresult, rmethod);
   movptr(rresult, Address(rresult, InstanceKlass::class_loader_data_offset()));
 }
 
+void MacroAssembler::load_method_holder(Register holder, Register method) {
+  movptr(holder, Address(method, Method::const_offset()));                      // ConstMethod*
+  movptr(holder, Address(holder, ConstMethod::constants_offset()));             // ConstantPool*
+  movptr(holder, Address(holder, ConstantPool::pool_holder_offset_in_bytes())); // InstanceKlass*
+}
+
 void MacroAssembler::load_klass(Register dst, Register src) {
 #ifdef _LP64
   if (UseCompressedClassPointers) {
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Thu May 30 19:49:55 2019 +0200
@@ -317,6 +317,8 @@
   void load_mirror(Register mirror, Register method, Register tmp = rscratch2);
   void load_method_holder_cld(Register rresult, Register rmethod);
 
+  void load_method_holder(Register holder, Register method);
+
   // oop manipulations
   void load_klass(Register dst, Register src);
   void store_klass(Register dst, Register src);
@@ -581,6 +583,11 @@
                            Register temp_reg,
                            Label& L_success);
 
+  void clinit_barrier(Register klass,
+                      Register thread,
+                      Label* L_fast_path = NULL,
+                      Label* L_slow_path = NULL);
+
   // method handles (JSR 292)
   Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
 
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Thu May 30 19:49:55 2019 +0200
@@ -974,6 +974,27 @@
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
   bs->c2i_entry_barrier(masm);
 
+  // Class initialization barrier for static methods
+  if (VM_Version::supports_fast_class_init_checks()) {
+    Label L_skip_barrier;
+    Register method = rbx;
+
+    { // Bypass the barrier for non-static methods
+      Register flags  = rscratch1;
+      __ movl(flags, Address(method, Method::access_flags_offset()));
+      __ testl(flags, JVM_ACC_STATIC);
+      __ jcc(Assembler::zero, L_skip_barrier); // non-static
+    }
+
+    Register klass = rscratch1;
+    __ load_method_holder(klass, method);
+    __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/);
+
+    __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
+
+    __ bind(L_skip_barrier);
+  }
+
   gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
 
   __ flush();
@@ -2140,6 +2161,17 @@
 
   int vep_offset = ((intptr_t)__ pc()) - start;
 
+  if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
+    Label L_skip_barrier;
+    Register klass = r10;
+    __ mov_metadata(klass, method->method_holder()); // InstanceKlass*
+    __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/);
+
+    __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
+
+    __ bind(L_skip_barrier);
+  }
+
 #ifdef COMPILER1
   // For Object.hashCode, System.identityHashCode try to pull hashCode from object header if available.
   if ((InlineObjectHash && method->intrinsic_id() == vmIntrinsics::_hashCode) || (method->intrinsic_id() == vmIntrinsics::_identityHashCode)) {
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp	Thu May 30 19:49:55 2019 +0200
@@ -2719,12 +2719,13 @@
 }
 
 void TemplateTable::resolve_cache_and_index(int byte_no,
-                                            Register Rcache,
+                                            Register cache,
                                             Register index,
                                             size_t index_size) {
   const Register temp = rbx;
-  assert_different_registers(Rcache, index, temp);
-
+  assert_different_registers(cache, index, temp);
+
+  Label L_clinit_barrier_slow;
   Label resolved;
 
   Bytecodes::Code code = bytecode();
@@ -2735,17 +2736,32 @@
   }
 
   assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
-  __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
+  __ get_cache_and_index_and_bytecode_at_bcp(cache, index, temp, byte_no, 1, index_size);
   __ cmpl(temp, code);  // have we resolved this bytecode?
   __ jcc(Assembler::equal, resolved);
 
   // resolve first time through
+  // Class initialization barrier slow path lands here as well.
+  __ bind(L_clinit_barrier_slow);
   address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
   __ movl(temp, code);
   __ call_VM(noreg, entry, temp);
   // Update registers with resolved info
-  __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
+  __ get_cache_and_index_at_bcp(cache, index, 1, index_size);
+
   __ bind(resolved);
+
+  // Class initialization barrier for static methods
+  if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
+    const Register method = temp;
+    const Register klass  = temp;
+    const Register thread = LP64_ONLY(r15_thread) NOT_LP64(noreg);
+    assert(thread != noreg, "x86_32 not supported");
+
+    __ load_resolved_method_at_index(byte_no, method, cache, index);
+    __ load_method_holder(klass, method);
+    __ clinit_barrier(klass, thread, NULL /*L_fast_path*/, &L_clinit_barrier_slow);
+  }
 }
 
 // The cache and index registers must be set before call
@@ -2794,11 +2810,6 @@
   assert_different_registers(itable_index, cache, index);
   // determine constant pool cache field offsets
   assert(is_invokevirtual == (byte_no == f2_byte), "is_invokevirtual flag redundant");
-  const int method_offset = in_bytes(
-    ConstantPoolCache::base_offset() +
-      ((byte_no == f2_byte)
-       ? ConstantPoolCacheEntry::f2_offset()
-       : ConstantPoolCacheEntry::f1_offset()));
   const int flags_offset = in_bytes(ConstantPoolCache::base_offset() +
                                     ConstantPoolCacheEntry::flags_offset());
   // access constant pool cache fields
@@ -2807,7 +2818,7 @@
 
   size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
   resolve_cache_and_index(byte_no, cache, index, index_size);
-    __ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
+  __ load_resolved_method_at_index(byte_no, method, cache, index);
 
   if (itable_index != noreg) {
     // pick up itable or appendix index from f2 also:
@@ -3862,9 +3873,7 @@
   __ profile_virtual_call(rdx, rbcp, rlocals);
 
   // Get declaring interface class from method, and itable index
-  __ movptr(rax, Address(rbx, Method::const_offset()));
-  __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
-  __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
+  __ load_method_holder(rax, rbx);
   __ movl(rbx, Address(rbx, Method::itable_index_offset()));
   __ subl(rbx, Method::itable_index_max);
   __ negl(rbx);
@@ -4003,7 +4012,7 @@
   __ jcc(Assembler::notEqual, slow_case_no_pop);
 
   // get InstanceKlass
-  __ load_resolved_klass_at_index(rcx, rdx, rcx);
+  __ load_resolved_klass_at_index(rcx, rcx, rdx);
   __ push(rcx);  // save the contexts of klass for initializing the header
 
   // make sure klass is initialized & doesn't have finalizer
@@ -4197,7 +4206,7 @@
   // Get superklass in rax and subklass in rbx
   __ bind(quicked);
   __ mov(rdx, rax); // Save object in rdx; rax needed for subtype check
-  __ load_resolved_klass_at_index(rcx, rbx, rax);
+  __ load_resolved_klass_at_index(rax, rcx, rbx);
 
   __ bind(resolved);
   __ load_klass(rbx, rdx);
@@ -4263,7 +4272,7 @@
   // Get superklass in rax and subklass in rdx
   __ bind(quicked);
   __ load_klass(rdx, rax);
-  __ load_resolved_klass_at_index(rcx, rbx, rax);
+  __ load_resolved_klass_at_index(rax, rcx, rbx);
 
   __ bind(resolved);
 
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/vm_version_x86.hpp	Thu May 30 19:49:55 2019 +0200
@@ -936,6 +936,11 @@
   // the intrinsic for java.lang.Thread.onSpinWait()
   static bool supports_on_spin_wait() { return supports_sse2(); }
 
+  // x86_64 supports fast class initialization checks for static methods.
+  static bool supports_fast_class_init_checks() {
+    return LP64_ONLY(true) NOT_LP64(false); // not implemented on x86_32
+  }
+
   // support functions for virtualization detection
  private:
   static void check_virt_cpuid(uint32_t idx, uint32_t *regs);
--- a/src/hotspot/cpu/x86/x86.ad	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/x86.ad	Thu May 30 19:49:55 2019 +0200
@@ -3153,30 +3153,6 @@
 
 // ====================LEGACY REPLICATE=======================================
 
-instruct Repl4B_mem(vecS dst, memory mem) %{
-  predicate(n->as_Vector()->length() == 4 && UseAVX > 0 && !VM_Version::supports_avx512vlbw());
-  match(Set dst (ReplicateB (LoadB mem)));
-  format %{ "punpcklbw $dst,$mem\n\t"
-            "pshuflw $dst,$dst,0x00\t! replicate4B" %}
-  ins_encode %{
-    __ punpcklbw($dst$$XMMRegister, $mem$$Address);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-instruct Repl8B_mem(vecD dst, memory mem) %{
-  predicate(n->as_Vector()->length() == 8 && UseAVX > 0 && !VM_Version::supports_avx512vlbw());
-  match(Set dst (ReplicateB (LoadB mem)));
-  format %{ "punpcklbw $dst,$mem\n\t"
-            "pshuflw $dst,$dst,0x00\t! replicate8B" %}
-  ins_encode %{
-    __ punpcklbw($dst$$XMMRegister, $mem$$Address);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 instruct Repl16B(vecX dst, rRegI src) %{
   predicate(n->as_Vector()->length() == 16 && !VM_Version::supports_avx512vlbw());
   match(Set dst (ReplicateB src));
@@ -3193,20 +3169,6 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct Repl16B_mem(vecX dst, memory mem) %{
-  predicate(n->as_Vector()->length() == 16 && UseAVX > 0 && !VM_Version::supports_avx512vlbw());
-  match(Set dst (ReplicateB (LoadB mem)));
-  format %{ "punpcklbw $dst,$mem\n\t"
-            "pshuflw $dst,$dst,0x00\n\t"
-            "punpcklqdq $dst,$dst\t! replicate16B" %}
-  ins_encode %{
-    __ punpcklbw($dst$$XMMRegister, $mem$$Address);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 instruct Repl32B(vecY dst, rRegI src) %{
   predicate(n->as_Vector()->length() == 32 && !VM_Version::supports_avx512vlbw());
   match(Set dst (ReplicateB src));
@@ -3225,22 +3187,6 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct Repl32B_mem(vecY dst, memory mem) %{
-  predicate(n->as_Vector()->length() == 32 && !VM_Version::supports_avx512vlbw());
-  match(Set dst (ReplicateB (LoadB mem)));
-  format %{ "punpcklbw $dst,$mem\n\t"
-            "pshuflw $dst,$dst,0x00\n\t"
-            "punpcklqdq $dst,$dst\n\t"
-            "vinserti128_high $dst,$dst\t! replicate32B" %}
-  ins_encode %{
-    __ punpcklbw($dst$$XMMRegister, $mem$$Address);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
-    __ vinserti128_high($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 instruct Repl64B(legVecZ dst, rRegI src) %{
   predicate(n->as_Vector()->length() == 64 && !VM_Version::supports_avx512vlbw());
   match(Set dst (ReplicateB src));
@@ -3261,24 +3207,6 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct Repl64B_mem(legVecZ dst, memory mem) %{
-  predicate(n->as_Vector()->length() == 64 && !VM_Version::supports_avx512vlbw());
-  match(Set dst (ReplicateB (LoadB mem)));
-  format %{ "punpcklbw $dst,$mem\n\t"
-            "pshuflw $dst,$dst,0x00\n\t"
-            "punpcklqdq $dst,$dst\n\t"
-            "vinserti128_high $dst,$dst\t"
-            "vinserti64x4 $dst,$dst,$dst,0x1\t! replicate64B" %}
-  ins_encode %{
-    __ punpcklbw($dst$$XMMRegister, $mem$$Address);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
-    __ vinserti128_high($dst$$XMMRegister, $dst$$XMMRegister);
-    __ vinserti64x4($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, 0x1);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 instruct Repl16B_imm(vecX dst, immI con) %{
   predicate(n->as_Vector()->length() == 16 && !VM_Version::supports_avx512vlbw());
   match(Set dst (ReplicateB con));
--- a/src/hotspot/cpu/x86/x86_64.ad	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/cpu/x86/x86_64.ad	Thu May 30 19:49:55 2019 +0200
@@ -874,6 +874,22 @@
   int framesize = C->frame_size_in_bytes();
   int bangsize = C->bang_size_in_bytes();
 
+  if (C->clinit_barrier_on_entry()) {
+    assert(VM_Version::supports_fast_class_init_checks(), "sanity");
+    assert(C->method()->holder()->is_being_initialized() || C->method()->holder()->is_initialized(),
+           "initialization should have been started");
+
+    Label L_skip_barrier;
+    Register klass = rscratch1;
+
+    __ mov_metadata(klass, C->method()->holder()->constant_encoding());
+    __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/);
+
+    __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
+
+    __ bind(L_skip_barrier);
+  }
+
   __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != NULL);
 
   C->set_frame_complete(cbuf.insts_size());
--- a/src/hotspot/os/aix/os_aix.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/os/aix/os_aix.cpp	Thu May 30 19:49:55 2019 +0200
@@ -2442,6 +2442,7 @@
   //
   // See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm
 
+  Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
   bool rc = ::mprotect(addr, size, prot) == 0 ? true : false;
 
   if (!rc) {
@@ -2482,6 +2483,7 @@
           // A valid strategy is just to try again. This usually works. :-/
 
           ::usleep(1000);
+          Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
           if (::mprotect(addr, size, prot) == 0) {
             const bool read_protected_2 =
               (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
--- a/src/hotspot/os/bsd/os_bsd.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Thu May 30 19:49:55 2019 +0200
@@ -1933,6 +1933,7 @@
   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
 #ifdef __OpenBSD__
   // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
+  Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
   if (::mprotect(addr, size, prot) == 0) {
     return true;
   }
@@ -2017,6 +2018,7 @@
 bool os::pd_uncommit_memory(char* addr, size_t size) {
 #ifdef __OpenBSD__
   // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
+  Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size));
   return ::mprotect(addr, size, PROT_NONE) == 0;
 #else
   uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
@@ -2085,6 +2087,7 @@
   assert(addr == bottom, "sanity check");
 
   size = align_up(pointer_delta(addr, bottom, 1) + size, os::Bsd::page_size());
+  Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot);
   return ::mprotect(bottom, size, prot) == 0;
 }
 
--- a/src/hotspot/os/linux/os_linux.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/os/linux/os_linux.cpp	Thu May 30 19:49:55 2019 +0200
@@ -3450,6 +3450,7 @@
   assert(addr == bottom, "sanity check");
 
   size = align_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size());
+  Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot);
   return ::mprotect(bottom, size, prot) == 0;
 }
 
--- a/src/hotspot/os/solaris/os_solaris.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Thu May 30 19:49:55 2019 +0200
@@ -2666,6 +2666,7 @@
 static bool solaris_mprotect(char* addr, size_t bytes, int prot) {
   assert(addr == (char*)align_down((uintptr_t)addr, os::vm_page_size()),
          "addr must be page aligned");
+  Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+bytes), prot);
   int retVal = mprotect(addr, bytes, prot);
   return retVal == 0;
 }
@@ -4229,6 +4230,7 @@
 
 // Mark the polling page as unreadable
 void os::make_polling_page_unreadable(void) {
+  Events::log(NULL, "Protecting polling page " INTPTR_FORMAT " with PROT_NONE", p2i(_polling_page));
   if (mprotect((char *)_polling_page, page_size, PROT_NONE) != 0) {
     fatal("Could not disable polling page");
   }
@@ -4236,6 +4238,7 @@
 
 // Mark the polling page as readable
 void os::make_polling_page_readable(void) {
+  Events::log(NULL, "Protecting polling page " INTPTR_FORMAT " with PROT_READ", p2i(_polling_page));
   if (mprotect((char *)_polling_page, page_size, PROT_READ) != 0) {
     fatal("Could not enable polling page");
   }
--- a/src/hotspot/share/Xusage.txt	Thu May 23 22:12:31 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-    -Xmixed           mixed mode execution (default)
-    -Xint             interpreted mode execution only
-    -Xbootclasspath:<directories and zip/jar files separated by ;>
-                      set search path for bootstrap classes and resources
-    -Xbootclasspath/a:<directories and zip/jar files separated by ;>
-                      append to end of bootstrap class path
-    -Xbootclasspath/p:<directories and zip/jar files separated by ;>
-                      prepend in front of bootstrap class path
-    -Xnoclassgc       disable class garbage collection
-    -Xlog:<opts>      control JVM logging, use -Xlog:help for details
-    -Xbatch           disable background compilation
-    -Xms<size>        set initial Java heap size
-    -Xmx<size>        set maximum Java heap size
-    -Xss<size>        set java thread stack size
-    -Xfuture          enable strictest checks, anticipating future default
-                      (deprecated)
-    -Xrs              reduce use of OS signals by Java/VM (see documentation)
-    -Xcheck:jni       perform additional checks for JNI functions
-    -Xshare:off	      do not attempt to use shared class data
-    -Xshare:auto      use shared class data if possible (default)
-    -Xshare:on	      require using shared class data, otherwise fail.
-
-The -X options are non-standard and subject to change without notice.
--- a/src/hotspot/share/c1/c1_LIRAssembler.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp	Thu May 30 19:49:55 2019 +0200
@@ -162,6 +162,9 @@
   return !method->is_static();
 }
 
+bool LIR_Assembler::needs_clinit_barrier_on_entry(ciMethod* method) const {
+  return VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier();
+}
 
 int LIR_Assembler::code_offset() const {
   return _masm->offset();
@@ -621,6 +624,9 @@
       }
       offsets()->set_value(CodeOffsets::Verified_Entry, _masm->offset());
       _masm->verified_entry();
+      if (needs_clinit_barrier_on_entry(compilation()->method())) {
+        clinit_barrier(compilation()->method());
+      }
       build_frame();
       offsets()->set_value(CodeOffsets::Frame_Complete, _masm->offset());
       break;
--- a/src/hotspot/share/c1/c1_LIRAssembler.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/c1/c1_LIRAssembler.hpp	Thu May 30 19:49:55 2019 +0200
@@ -81,6 +81,9 @@
   // returns offset of icache check
   int check_icache();
 
+  bool needs_clinit_barrier_on_entry(ciMethod* method) const;
+  void clinit_barrier(ciMethod* method);
+
   void jobject2reg(jobject o, Register reg);
   void jobject2reg_with_patching(Register reg, CodeEmitInfo* info);
 
--- a/src/hotspot/share/ci/ciMethod.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/ci/ciMethod.cpp	Thu May 30 19:49:55 2019 +0200
@@ -933,6 +933,13 @@
   return get_Method()->is_ignored_by_security_stack_walk();
 }
 
+// ------------------------------------------------------------------
+// ciMethod::needs_clinit_barrier
+//
+bool ciMethod::needs_clinit_barrier() const {
+  check_is_loaded();
+  return is_static() && !holder()->is_initialized();
+}
 
 // ------------------------------------------------------------------
 // invokedynamic support
--- a/src/hotspot/share/ci/ciMethod.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/ci/ciMethod.hpp	Thu May 30 19:49:55 2019 +0200
@@ -245,6 +245,8 @@
 
   ResourceBitMap live_local_oops_at_bci(int bci);
 
+  bool needs_clinit_barrier() const;
+
 #ifdef COMPILER1
   const BitMap& bci_block_start();
 #endif
--- a/src/hotspot/share/ci/ciReplay.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/ci/ciReplay.cpp	Thu May 30 19:49:55 2019 +0200
@@ -532,7 +532,11 @@
     // old version w/o comp_level
     if (had_error() && (error_message() == comp_level_label)) {
       // use highest available tier
-      comp_level = TieredCompilation ? TieredStopAtLevel : CompLevel_highest_tier;
+      if (TieredCompilation) {
+        comp_level = TieredStopAtLevel;
+      } else {
+        comp_level = CompLevel_highest_tier;
+      }
     }
     if (!is_valid_comp_level(comp_level)) {
       return;
--- a/src/hotspot/share/code/nmethod.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/code/nmethod.cpp	Thu May 30 19:49:55 2019 +0200
@@ -1261,7 +1261,7 @@
 
 void nmethod::unlink_from_method() {
   if (method() != NULL) {
-    method()->unlink_code();
+    method()->unlink_code(this);
   }
 }
 
--- a/src/hotspot/share/compiler/abstractDisassembler.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/compiler/abstractDisassembler.cpp	Thu May 30 19:49:55 2019 +0200
@@ -213,7 +213,7 @@
                 st->print("                   long");
               } else {
                 if (((uintptr_t)(here)&0x07) == 0) {
-                  st->print("%23.1ld", *((jlong*)here));
+                  st->print(JLONG_FORMAT_W(23), *((jlong*)here));
                 }
               }
               st->fill_to(align += 3*tsize);
--- a/src/hotspot/share/compiler/disassembler.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/compiler/disassembler.cpp	Thu May 30 19:49:55 2019 +0200
@@ -774,13 +774,14 @@
     // Match "[lib]jvm[^/]*" in jvm_path.
     const char* base = buf;
     const char* p = strrchr(buf, *os::file_separator());
+    if (p != NULL) lib_offset = p - base + 1; // this points to the first char after separator
 #ifdef _WIN32
     p = strstr(p ? p : base, "jvm");
+    if (p != NULL) jvm_offset = p - base;     // this points to 'j' in jvm.
 #else
     p = strstr(p ? p : base, "libjvm");
+    if (p != NULL) jvm_offset = p - base + 3; // this points to 'j' in libjvm.
 #endif
-    if (p != NULL) lib_offset = p - base + 1;
-    if (p != NULL) jvm_offset = p - base;
   }
 #endif
 
@@ -794,11 +795,13 @@
     // 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so
     strcpy(&buf[jvm_offset], hsdis_library_name);
     strcat(&buf[jvm_offset], os::dll_file_extension());
+    if (Verbose) st->print_cr("Trying to load: %s", buf);
     _library = os::dll_load(buf, ebuf, sizeof ebuf);
     if (_library == NULL && lib_offset >= 0) {
       // 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
       strcpy(&buf[lib_offset], hsdis_library_name);
       strcat(&buf[lib_offset], os::dll_file_extension());
+      if (Verbose) st->print_cr("Trying to load: %s", buf);
       _library = os::dll_load(buf, ebuf, sizeof ebuf);
     }
     if (_library == NULL && lib_offset > 0) {
@@ -809,6 +812,7 @@
         lib_offset = p - buf + 1;
         strcpy(&buf[lib_offset], hsdis_library_name);
         strcat(&buf[lib_offset], os::dll_file_extension());
+        if (Verbose) st->print_cr("Trying to load: %s", buf);
         _library = os::dll_load(buf, ebuf, sizeof ebuf);
       }
     }
@@ -817,6 +821,7 @@
     // 4. hsdis-<arch>.so  (using LD_LIBRARY_PATH)
     strcpy(&buf[0], hsdis_library_name);
     strcat(&buf[0], os::dll_file_extension());
+    if (Verbose) st->print_cr("Trying to load: %s via LD_LIBRARY_PATH or equivalent", buf);
     _library = os::dll_load(buf, ebuf, sizeof ebuf);
   }
 
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp	Thu May 30 19:49:55 2019 +0200
@@ -295,7 +295,7 @@
          call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry);
 }
 
-bool ShenandoahBarrierSetC2::is_shenandoah_wb_call(Node* call) {
+bool ShenandoahBarrierSetC2::is_shenandoah_lrb_call(Node* call) {
   return call->is_CallLeaf() &&
          call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT);
 }
@@ -472,7 +472,7 @@
   return TypeFunc::make(domain, range);
 }
 
-const TypeFunc* ShenandoahBarrierSetC2::shenandoah_write_barrier_Type() {
+const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() {
   const Type **fields = TypeTuple::fields(1);
   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
@@ -710,30 +710,6 @@
   BarrierSetC2::clone(kit, src, dst, size, is_array);
 }
 
-Node* ShenandoahBarrierSetC2::obj_allocate(PhaseMacroExpand* macro, Node* ctrl, Node* mem, Node* toobig_false, Node* size_in_bytes,
-                                           Node*& i_o, Node*& needgc_ctrl,
-                                           Node*& fast_oop_ctrl, Node*& fast_oop_rawmem,
-                                           intx prefetch_lines) const {
-  PhaseIterGVN& igvn = macro->igvn();
-
-  // Allocate several words more for the Shenandoah brooks pointer.
-  size_in_bytes = new AddXNode(size_in_bytes, igvn.MakeConX(ShenandoahForwarding::byte_size()));
-  macro->transform_later(size_in_bytes);
-
-  Node* fast_oop = BarrierSetC2::obj_allocate(macro, ctrl, mem, toobig_false, size_in_bytes,
-                                              i_o, needgc_ctrl, fast_oop_ctrl, fast_oop_rawmem,
-                                              prefetch_lines);
-
-  // Bump up object for Shenandoah brooks pointer.
-  fast_oop = new AddPNode(macro->top(), fast_oop, igvn.MakeConX(ShenandoahForwarding::byte_size()));
-  macro->transform_later(fast_oop);
-
-  // Initialize Shenandoah brooks pointer to point to the object itself.
-  fast_oop_rawmem = macro->make_store(fast_oop_ctrl, fast_oop_rawmem, fast_oop, ShenandoahForwarding::byte_offset(), fast_oop, T_OBJECT);
-
-  return fast_oop;
-}
-
 // Support for GC barriers emitted during parsing
 bool ShenandoahBarrierSetC2::is_gc_barrier_node(Node* node) const {
   if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) return true;
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp	Thu May 30 19:49:55 2019 +0200
@@ -93,7 +93,7 @@
   static ShenandoahBarrierSetC2* bsc2();
 
   static bool is_shenandoah_wb_pre_call(Node* call);
-  static bool is_shenandoah_wb_call(Node* call);
+  static bool is_shenandoah_lrb_call(Node* call);
   static bool is_shenandoah_marking_if(PhaseTransform *phase, Node* n);
   static bool is_shenandoah_state_load(Node* n);
   static bool has_only_shenandoah_wb_pre_uses(Node* n);
@@ -102,17 +102,12 @@
 
   static const TypeFunc* write_ref_field_pre_entry_Type();
   static const TypeFunc* shenandoah_clone_barrier_Type();
-  static const TypeFunc* shenandoah_write_barrier_Type();
+  static const TypeFunc* shenandoah_load_reference_barrier_Type();
   virtual bool has_load_barriers() const { return true; }
 
   // This is the entry-point for the backend to perform accesses through the Access API.
   virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const;
 
-  virtual Node* obj_allocate(PhaseMacroExpand* macro, Node* ctrl, Node* mem, Node* toobig_false, Node* size_in_bytes,
-                             Node*& i_o, Node*& needgc_ctrl,
-                             Node*& fast_oop_ctrl, Node*& fast_oop_rawmem,
-                             intx prefetch_lines) const;
-
   // These are general helper methods used by C2
   virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const;
   virtual void clone_barrier_at_expansion(ArrayCopyNode* ac, Node* call, PhaseIterGVN& igvn) const;
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Thu May 30 19:49:55 2019 +0200
@@ -1093,7 +1093,7 @@
   mm->set_memory_at(Compile::AliasIdxRaw, raw_mem);
   phase->register_new_node(mm, ctrl);
 
-  Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_write_barrier_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT), "shenandoah_write_barrier", TypeRawPtr::BOTTOM);
+  Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT), "shenandoah_load_reference_barrier", TypeRawPtr::BOTTOM);
   call->init_req(TypeFunc::Control, ctrl);
   call->init_req(TypeFunc::I_O, phase->C->top());
   call->init_req(TypeFunc::Memory, mm);
@@ -1191,12 +1191,6 @@
 void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
   ShenandoahBarrierSetC2State* state = ShenandoahBarrierSetC2::bsc2()->state();
 
-  // Collect raw memory state at CFG points in the entire graph and
-  // record it in memory_nodes. Optimize the raw memory graph in the
-  // process. Optimizing the memory graph also makes the memory graph
-  // simpler.
-  GrowableArray<MemoryGraphFixer*> memory_graph_fixers;
-
   Unique_Node_List uses;
   for (int i = 0; i < state->enqueue_barriers_count(); i++) {
     Node* barrier = state->enqueue_barrier(i);
@@ -1412,6 +1406,22 @@
     }
   }
 
+  for (int i = 0; i < state->load_reference_barriers_count(); i++) {
+    ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
+    if (lrb->get_barrier_strength() == ShenandoahLoadReferenceBarrierNode::NONE) {
+      continue;
+    }
+    Node* ctrl = phase->get_ctrl(lrb);
+    IdealLoopTree* loop = phase->get_loop(ctrl);
+    if (loop->_head->is_OuterStripMinedLoop()) {
+      // Expanding a barrier here will break loop strip mining
+      // verification. Transform the loop so the loop nest doesn't
+      // appear as strip mined.
+      OuterStripMinedLoopNode* outer = loop->_head->as_OuterStripMinedLoop();
+      hide_strip_mined_loop(outer, outer->unique_ctrl_out()->as_CountedLoop(), phase);
+    }
+  }
+
   // Expand load-reference-barriers
   MemoryGraphFixer fixer(Compile::AliasIdxRaw, true, phase);
   Unique_Node_List uses_to_ignore;
@@ -1431,7 +1441,6 @@
     Node* raw_mem = fixer.find_mem(ctrl, lrb);
     Node* init_raw_mem = raw_mem;
     Node* raw_mem_for_ctrl = fixer.find_mem(ctrl, NULL);
-    // int alias = phase->C->get_alias_index(lrb->adr_type());
 
     IdealLoopTree *loop = phase->get_loop(ctrl);
     CallStaticJavaNode* unc = lrb->pin_and_expand_null_check(phase->igvn());
@@ -1455,7 +1464,7 @@
     assert(val->bottom_type()->make_oopptr(), "need oop");
     assert(val->bottom_type()->make_oopptr()->const_oop() == NULL, "expect non-constant");
 
-    enum { _heap_stable = 1, _not_cset, _not_equal, _evac_path, _null_path, PATH_LIMIT };
+    enum { _heap_stable = 1, _not_cset, _fwded, _evac_path, _null_path, PATH_LIMIT };
     Node* region = new RegionNode(PATH_LIMIT);
     Node* val_phi = new PhiNode(region, uncasted_val->bottom_type()->is_oopptr());
     Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
@@ -1505,36 +1514,48 @@
       IfNode* iff = unc_ctrl->in(0)->as_If();
       phase->igvn().replace_input_of(iff, 1, phase->igvn().intcon(1));
     }
-    Node* addr = new AddPNode(new_val, uncasted_val, phase->igvn().MakeConX(ShenandoahForwarding::byte_offset()));
+    Node* addr = new AddPNode(new_val, uncasted_val, phase->igvn().MakeConX(oopDesc::mark_offset_in_bytes()));
     phase->register_new_node(addr, ctrl);
-    assert(val->bottom_type()->isa_oopptr(), "what else?");
-    const TypePtr* obj_type =  val->bottom_type()->is_oopptr();
-    const TypePtr* adr_type = TypeRawPtr::BOTTOM;
-    Node* fwd = new LoadPNode(ctrl, raw_mem, addr, adr_type, obj_type, MemNode::unordered);
-    phase->register_new_node(fwd, ctrl);
+    assert(new_val->bottom_type()->isa_oopptr(), "what else?");
+    Node* markword = new LoadXNode(ctrl, raw_mem, addr, TypeRawPtr::BOTTOM, TypeX_X, MemNode::unordered);
+    phase->register_new_node(markword, ctrl);
+
+    // Test if object is forwarded. This is the case if lowest two bits are set.
+    Node* masked = new AndXNode(markword, phase->igvn().MakeConX(markOopDesc::lock_mask_in_place));
+    phase->register_new_node(masked, ctrl);
+    Node* cmp = new CmpXNode(masked, phase->igvn().MakeConX(markOopDesc::marked_value));
+    phase->register_new_node(cmp, ctrl);
 
     // Only branch to LRB stub if object is not forwarded; otherwise reply with fwd ptr
-    Node* cmp = new CmpPNode(fwd, new_val);
-    phase->register_new_node(cmp, ctrl);
-    Node* bol = new BoolNode(cmp, BoolTest::eq);
+    Node* bol = new BoolNode(cmp, BoolTest::eq); // Equals 3 means it's forwarded
     phase->register_new_node(bol, ctrl);
 
-    IfNode* iff = new IfNode(ctrl, bol, PROB_UNLIKELY(0.999), COUNT_UNKNOWN);
-    if (reg2_ctrl == NULL) reg2_ctrl = iff;
+    IfNode* iff = new IfNode(ctrl, bol, PROB_LIKELY(0.999), COUNT_UNKNOWN);
     phase->register_control(iff, loop, ctrl);
-    Node* if_not_eq = new IfFalseNode(iff);
-    phase->register_control(if_not_eq, loop, iff);
-    Node* if_eq = new IfTrueNode(iff);
-    phase->register_control(if_eq, loop, iff);
+    Node* if_fwd = new IfTrueNode(iff);
+    phase->register_control(if_fwd, loop, iff);
+    Node* if_not_fwd = new IfFalseNode(iff);
+    phase->register_control(if_not_fwd, loop, iff);
+
+    // Decode forward pointer: since we already have the lowest bits, we can just subtract them
+    // from the mark word without the need for large immediate mask.
+    Node* masked2 = new SubXNode(markword, masked);
+    phase->register_new_node(masked2, if_fwd);
+    Node* fwdraw = new CastX2PNode(masked2);
+    fwdraw->init_req(0, if_fwd);
+    phase->register_new_node(fwdraw, if_fwd);
+    Node* fwd = new CheckCastPPNode(NULL, fwdraw, val->bottom_type());
+    phase->register_new_node(fwd, if_fwd);
 
     // Wire up not-equal-path in slots 3.
-    region->init_req(_not_equal, if_not_eq);
-    val_phi->init_req(_not_equal, fwd);
-    raw_mem_phi->init_req(_not_equal, raw_mem);
+    region->init_req(_fwded, if_fwd);
+    val_phi->init_req(_fwded, fwd);
+    raw_mem_phi->init_req(_fwded, raw_mem);
 
-    // Call wb-stub and wire up that path in slots 4
+    // Call lrb-stub and wire up that path in slots 4
     Node* result_mem = NULL;
-    ctrl = if_eq;
+    ctrl = if_not_fwd;
+    fwd = new_val;
     call_lrb_stub(ctrl, fwd, result_mem, raw_mem, phase);
     region->init_req(_evac_path, ctrl);
     val_phi->init_req(_evac_path, fwd);
@@ -1979,7 +2000,7 @@
   nodes.push(root);
   for (uint next = 0; next < nodes.size(); next++) {
     Node *n  = nodes.at(next);
-    if (ShenandoahBarrierSetC2::is_shenandoah_wb_call(n)) {
+    if (ShenandoahBarrierSetC2::is_shenandoah_lrb_call(n)) {
       controls.push(n);
       if (trace) { tty->print("XXXXXX verifying"); n->dump(); }
       for (uint next2 = 0; next2 < controls.size(); next2++) {
@@ -2595,7 +2616,11 @@
                 IdealLoopTree* l = loop;
                 create_phi = false;
                 while (l != _phase->ltree_root()) {
-                  if (_phase->is_dominator(l->_head, u) && _phase->is_dominator(_phase->idom(u), l->_head)) {
+                  Node* head = l->_head;
+                  if (head->in(0) == NULL) {
+                    head = _phase->get_ctrl(head);
+                  }
+                  if (_phase->is_dominator(head, u) && _phase->is_dominator(_phase->idom(u), head)) {
                     create_phi = true;
                     do_check = false;
                     break;
@@ -3123,11 +3148,7 @@
         break;
       }
       case Op_CallStaticJava: {
-        // If it's an deopt-call we don't need barriers because
-        // the LRB will be applied when unpacking the deopt frame.
-        if (n->as_CallStaticJava()->uncommon_trap_request() == 0) {
-          strength = STRONG;
-        }
+        strength = STRONG;
         break;
       }
       case Op_CallDynamicJava:
--- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp	Thu May 30 19:49:55 2019 +0200
@@ -60,6 +60,9 @@
   stringStream ss;
   r->print_on(&ss);
 
+  stringStream mw_ss;
+  obj->mark()->print_on(&mw_ss);
+
   ShenandoahMarkingContext* const ctx = heap->marking_context();
 
   msg.append("  " PTR_FORMAT " - klass " PTR_FORMAT " %s\n", p2i(obj), p2i(obj->klass()), obj->klass()->external_name());
@@ -69,6 +72,7 @@
   if (heap->traversal_gc() != NULL) {
     msg.append("    %3s in traversal set\n",         heap->traversal_gc()->traversal_set()->is_in((HeapWord*) obj) ? "" : "not");
   }
+  msg.append("  mark:%s\n", mw_ss.as_string());
   msg.append("  region: %s", ss.as_string());
 }
 
@@ -250,7 +254,7 @@
                   file, line);
   }
 
-  size_t alloc_size = obj->size() + ShenandoahForwarding::word_size();
+  size_t alloc_size = obj->size();
   if (alloc_size > ShenandoahHeapRegion::humongous_threshold_words()) {
     size_t idx = r->region_number();
     size_t num_regions = ShenandoahHeapRegion::required_regions(alloc_size * HeapWordSize);
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp	Thu May 30 19:49:55 2019 +0200
@@ -26,7 +26,6 @@
 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
-#include "gc/shenandoah/shenandoahForwarding.hpp"
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
@@ -42,7 +41,7 @@
 class ShenandoahBarrierSetC1;
 class ShenandoahBarrierSetC2;
 
-template <bool STOREVAL_WRITE_BARRIER>
+template <bool STOREVAL_EVAC_BARRIER>
 class ShenandoahUpdateRefsForOopClosure: public BasicOopIterateClosure {
 private:
   ShenandoahHeap* _heap;
@@ -51,7 +50,7 @@
   template <class T>
   inline void do_oop_work(T* p) {
     oop o;
-    if (STOREVAL_WRITE_BARRIER) {
+    if (STOREVAL_EVAC_BARRIER) {
       o = _heap->evac_update_with_forwarded(p);
       if (!CompressedOops::is_null(o)) {
         _bs->enqueue(o);
@@ -97,10 +96,10 @@
   return true;
 }
 
-template <class T, bool STOREVAL_WRITE_BARRIER>
+template <class T, bool STOREVAL_EVAC_BARRIER>
 void ShenandoahBarrierSet::write_ref_array_loop(HeapWord* start, size_t count) {
   assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled");
-  ShenandoahUpdateRefsForOopClosure<STOREVAL_WRITE_BARRIER> cl;
+  ShenandoahUpdateRefsForOopClosure<STOREVAL_EVAC_BARRIER> cl;
   T* dst = (T*) start;
   for (size_t i = 0; i < count; i++) {
     cl.do_oop(dst++);
@@ -114,15 +113,15 @@
   if (_heap->is_concurrent_traversal_in_progress()) {
     ShenandoahEvacOOMScope oom_evac_scope;
     if (UseCompressedOops) {
-      write_ref_array_loop<narrowOop, /* wb = */ true>(start, count);
+      write_ref_array_loop<narrowOop, /* evac = */ true>(start, count);
     } else {
-      write_ref_array_loop<oop,       /* wb = */ true>(start, count);
+      write_ref_array_loop<oop,       /* evac = */ true>(start, count);
     }
   } else {
     if (UseCompressedOops) {
-      write_ref_array_loop<narrowOop, /* wb = */ false>(start, count);
+      write_ref_array_loop<narrowOop, /* evac = */ false>(start, count);
     } else {
-      write_ref_array_loop<oop,       /* wb = */ false>(start, count);
+      write_ref_array_loop<oop,       /* evac = */ false>(start, count);
     }
   }
 }
@@ -207,10 +206,10 @@
   shenandoah_assert_correct(NULL, obj);
   if (_heap->is_concurrent_traversal_in_progress()) {
     ShenandoahEvacOOMScope oom_evac_scope;
-    ShenandoahUpdateRefsForOopClosure</* wb = */ true> cl;
+    ShenandoahUpdateRefsForOopClosure</* evac = */ true> cl;
     obj->oop_iterate(&cl);
   } else {
-    ShenandoahUpdateRefsForOopClosure</* wb = */ false> cl;
+    ShenandoahUpdateRefsForOopClosure</* evac = */ false> cl;
     obj->oop_iterate(&cl);
   }
 }
@@ -262,7 +261,7 @@
       ShenandoahHeapRegion* r = _heap->heap_region_containing(obj);
       assert(r->is_cset(), "sanity");
 
-      HeapWord* cur = (HeapWord*)obj + obj->size() + ShenandoahForwarding::word_size();
+      HeapWord* cur = (HeapWord*)obj + obj->size();
 
       size_t count = 0;
       while ((cur < r->top()) && ctx->is_marked(oop(cur)) && (count++ < max)) {
@@ -270,7 +269,7 @@
         if (oopDesc::equals_raw(cur_oop, resolve_forwarded_not_null(cur_oop))) {
           _heap->evacuate_object(cur_oop, thread);
         }
-        cur = cur + cur_oop->size() + ShenandoahForwarding::word_size();
+        cur = cur + cur_oop->size();
       }
     }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp	Thu May 30 19:49:55 2019 +0200
@@ -35,8 +35,8 @@
 public:
   enum ArrayCopyStoreValMode {
     NONE,
-    READ_BARRIER,
-    WRITE_BARRIER
+    RESOLVE_BARRIER,
+    EVAC_BARRIER
   };
 private:
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp	Thu May 30 19:49:55 2019 +0200
@@ -199,10 +199,10 @@
   switch (storeval_mode) {
     case NONE:
       return arraycopy_loop<T, CHECKCAST, SATB, NONE>(src, dst, length, bound, disjoint);
-    case READ_BARRIER:
-      return arraycopy_loop<T, CHECKCAST, SATB, READ_BARRIER>(src, dst, length, bound, disjoint);
-    case WRITE_BARRIER:
-      return arraycopy_loop<T, CHECKCAST, SATB, WRITE_BARRIER>(src, dst, length, bound, disjoint);
+    case RESOLVE_BARRIER:
+      return arraycopy_loop<T, CHECKCAST, SATB, RESOLVE_BARRIER>(src, dst, length, bound, disjoint);
+    case EVAC_BARRIER:
+      return arraycopy_loop<T, CHECKCAST, SATB, EVAC_BARRIER>(src, dst, length, bound, disjoint);
     default:
       ShouldNotReachHere();
       return true; // happy compiler
@@ -268,10 +268,10 @@
       switch (STOREVAL_MODE) {
       case NONE:
         break;
-      case READ_BARRIER:
-      case WRITE_BARRIER:
-        // The write-barrier case cannot really happen. It's traversal-only and traversal
-        // doesn't currently use SATB. And even if it did, it would not be fatal to just do the normal RB here.
+      case RESOLVE_BARRIER:
+      case EVAC_BARRIER:
+        // The evac-barrier case cannot really happen. It's traversal-only and traversal
+        // doesn't currently use SATB. And even if it did, it would not be fatal to just do the normal resolve here.
         prev_obj = ShenandoahBarrierSet::resolve_forwarded_not_null(prev_obj);
       }
       if (!ctx->is_marked(prev_obj)) {
@@ -293,10 +293,10 @@
     switch (STOREVAL_MODE) {
     case NONE:
       break;
-    case READ_BARRIER:
+    case RESOLVE_BARRIER:
       obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
       break;
-    case WRITE_BARRIER:
+    case EVAC_BARRIER:
       if (_heap->in_collection_set(obj)) {
         oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
         if (oopDesc::equals_raw(forw, obj)) {
@@ -337,9 +337,9 @@
   ArrayCopyStoreValMode storeval_mode;
   if (heap->has_forwarded_objects()) {
     if (heap->is_concurrent_traversal_in_progress()) {
-      storeval_mode = WRITE_BARRIER;
+      storeval_mode = EVAC_BARRIER;
     } else if (heap->is_update_refs_in_progress()) {
-      storeval_mode = READ_BARRIER;
+      storeval_mode = RESOLVE_BARRIER;
     } else {
       assert(heap->is_idle() || heap->is_evacuation_in_progress(), "must not have anything in progress");
       storeval_mode = NONE; // E.g. during evac or outside cycle
--- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp	Thu May 30 19:49:55 2019 +0200
@@ -26,6 +26,7 @@
 #include "code/nmethod.hpp"
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
+#include "gc/shenandoah/shenandoahUtils.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 
@@ -120,11 +121,10 @@
   }
 };
 
-ShenandoahCodeRoots::PaddedLock ShenandoahCodeRoots::_recorded_nms_lock;
 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
+ShenandoahLock                     ShenandoahCodeRoots::_recorded_nms_lock;
 
 void ShenandoahCodeRoots::initialize() {
-  _recorded_nms_lock._lock = 0;
   _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
 }
 
@@ -134,15 +134,15 @@
     case 1:
       break;
     case 2: {
+      assert_locked_or_safepoint(CodeCache_lock);
+      ShenandoahLocker locker(CodeCache_lock->owned_by_self() ? NULL : &_recorded_nms_lock);
+
       ShenandoahNMethodOopDetector detector;
       nm->oops_do(&detector);
 
       if (detector.has_oops()) {
         ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
         nmr->assert_alive_and_correct();
-
-        ShenandoahCodeRootsLock lock(true);
-
         int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
         if (idx != -1) {
           ShenandoahNMethod* old = _recorded_nms->at(idx);
@@ -166,12 +166,13 @@
       break;
     }
     case 2: {
+      assert_locked_or_safepoint(CodeCache_lock);
+      ShenandoahLocker locker(CodeCache_lock->owned_by_self() ? NULL : &_recorded_nms_lock);
+
       ShenandoahNMethodOopDetector detector;
       nm->oops_do(&detector, /* allow_zombie = */ true);
 
       if (detector.has_oops()) {
-        ShenandoahCodeRootsLock lock(true);
-
         int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
         assert(idx != -1, "nmethod " PTR_FORMAT " should be registered", p2i(nm));
         ShenandoahNMethod* old = _recorded_nms->at(idx);
@@ -199,7 +200,7 @@
       break;
     }
     case 2: {
-      ShenandoahCodeRoots::acquire_lock(false);
+      CodeCache_lock->lock();
       break;
     }
     default:
@@ -215,7 +216,7 @@
       break;
     }
     case 2: {
-      ShenandoahCodeRoots::release_lock(false);
+      CodeCache_lock->unlock();
       break;
     }
     default:
@@ -245,14 +246,6 @@
   }
 }
 
-ShenandoahAllCodeRootsIterator ShenandoahCodeRoots::iterator() {
-  return ShenandoahAllCodeRootsIterator();
-}
-
-ShenandoahCsetCodeRootsIterator ShenandoahCodeRoots::cset_iterator() {
-  return ShenandoahCsetCodeRootsIterator();
-}
-
 void ShenandoahAllCodeRootsIterator::possibly_parallel_blobs_do(CodeBlobClosure *f) {
   ShenandoahCodeRootsIterator::dispatch_parallel_blobs_do<false>(f);
 }
--- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp	Thu May 30 19:49:55 2019 +0200
@@ -26,12 +26,12 @@
 
 #include "code/codeCache.hpp"
 #include "gc/shenandoah/shenandoahSharedVariables.hpp"
+#include "gc/shenandoah/shenandoahLock.hpp"
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
 
 class ShenandoahHeap;
 class ShenandoahHeapRegion;
-class ShenandoahCodeRootsLock;
 
 class ShenandoahParallelCodeHeapIterator {
   friend class CodeCache;
@@ -51,6 +51,11 @@
 private:
   ShenandoahParallelCodeHeapIterator* _iters;
   int                       _length;
+
+private:
+  // Noncopyable.
+  ShenandoahParallelCodeCacheIterator(const ShenandoahParallelCodeCacheIterator& o);
+  ShenandoahParallelCodeCacheIterator& operator=(const ShenandoahParallelCodeCacheIterator& o);
 public:
   ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps);
   ~ShenandoahParallelCodeCacheIterator();
@@ -119,7 +124,6 @@
 
 class ShenandoahCodeRoots : public CHeapObj<mtGC> {
   friend class ShenandoahHeap;
-  friend class ShenandoahCodeRootsLock;
   friend class ShenandoahCodeRootsIterator;
 
 public:
@@ -127,74 +131,9 @@
   static void add_nmethod(nmethod* nm);
   static void remove_nmethod(nmethod* nm);
 
-  /**
-   * Provides the iterator over all nmethods in the code cache that have oops.
-   * @return
-   */
-  static ShenandoahAllCodeRootsIterator iterator();
-
-  /**
-   * Provides the iterator over nmethods that have at least one oop in collection set.
-   * @return
-   */
-  static ShenandoahCsetCodeRootsIterator cset_iterator();
-
 private:
-  struct PaddedLock {
-    DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile int));
-    volatile int _lock;
-    DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
-  };
-
-  static PaddedLock _recorded_nms_lock;
   static GrowableArray<ShenandoahNMethod*>* _recorded_nms;
-
-  static void acquire_lock(bool write) {
-    volatile int* loc = &_recorded_nms_lock._lock;
-    if (write) {
-      while ((OrderAccess::load_acquire(loc) != 0) ||
-             Atomic::cmpxchg(-1, loc, 0) != 0) {
-        SpinPause();
-      }
-      assert (*loc == -1, "acquired for write");
-    } else {
-      while (true) {
-        int cur = OrderAccess::load_acquire(loc);
-        if (cur >= 0) {
-          if (Atomic::cmpxchg(cur + 1, loc, cur) == cur) {
-            // Success!
-            assert (*loc > 0, "acquired for read");
-            return;
-          }
-        }
-        SpinPause();
-      }
-    }
-  }
-
-  static void release_lock(bool write) {
-    volatile int* loc = &ShenandoahCodeRoots::_recorded_nms_lock._lock;
-    if (write) {
-      OrderAccess::release_store_fence(loc, 0);
-    } else {
-      Atomic::dec(loc);
-    }
-  }
-};
-
-// Very simple unranked read-write lock
-class ShenandoahCodeRootsLock : public StackObj {
-  friend class ShenandoahCodeRoots;
-private:
-  const bool _write;
-public:
-  ShenandoahCodeRootsLock(bool write) : _write(write) {
-    ShenandoahCodeRoots::acquire_lock(write);
-  }
-
-  ~ShenandoahCodeRootsLock() {
-    ShenandoahCodeRoots::release_lock(_write);
-  }
+  static ShenandoahLock                     _recorded_nms_lock;
 };
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp	Thu May 30 19:49:55 2019 +0200
@@ -25,7 +25,6 @@
 #define SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP
 
 #include "gc/shenandoah/shenandoahAsserts.hpp"
-#include "gc/shenandoah/shenandoahForwarding.hpp"
 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
 #include "gc/shenandoah/shenandoahConcurrentMark.hpp"
 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
@@ -70,7 +69,7 @@
 inline void ShenandoahConcurrentMark::count_liveness(jushort* live_data, oop obj) {
   size_t region_idx = _heap->heap_region_index_containing(obj);
   ShenandoahHeapRegion* region = _heap->get_region(region_idx);
-  size_t size = obj->size() + ShenandoahForwarding::word_size();
+  size_t size = obj->size();
 
   if (!region->is_humongous_start()) {
     assert(!region->is_humongous(), "Cannot have continuations here");
--- a/src/hotspot/share/gc/shenandoah/shenandoahForwarding.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahForwarding.hpp	Thu May 30 19:49:55 2019 +0200
@@ -28,68 +28,11 @@
 #include "utilities/globalDefinitions.hpp"
 
 class ShenandoahForwarding {
-  /*
-   * Notes:
-   *
-   *  a. It is important to have byte_offset and word_offset return constant
-   *     expressions, because that will allow to constant-fold forwarding ptr
-   *     accesses. This is not a problem in JIT compilers that would generate
-   *     the code once, but it is problematic in GC hotpath code.
-   *
-   *  b. With filler object mechanics, we may need to allocate more space for
-   *     the forwarding ptr to meet alignment requirements for objects. This
-   *     means *_offset and *_size calls are NOT interchangeable. The accesses
-   *     to forwarding ptrs should always be via *_offset. Storage size
-   *     calculations should always be via *_size.
-   */
-
 public:
-  /* Offset from the object start, in HeapWords. */
-  static inline int word_offset() {
-    return -1; // exactly one HeapWord
-  }
-
-  /* Offset from the object start, in bytes. */
-  static inline int byte_offset() {
-    return -HeapWordSize; // exactly one HeapWord
-  }
-
-  /* Allocated size, in HeapWords. */
-  static inline uint word_size() {
-    return (uint) MinObjAlignment;
-  }
-
-  /* Allocated size, in bytes */
-  static inline uint byte_size() {
-    return (uint) MinObjAlignmentInBytes;
-  }
-
-  /* Assert basic stuff once at startup. */
-  static void initial_checks() {
-    guarantee (MinObjAlignment > 0, "sanity, word_size is correct");
-    guarantee (MinObjAlignmentInBytes > 0, "sanity, byte_size is correct");
-  }
-
-  /* Initializes forwarding pointer (to self).
-   */
-  static inline void initialize(oop obj);
-
   /* Gets forwardee from the given object.
    */
   static inline oop get_forwardee(oop obj);
 
-  /* Tries to atomically update forwardee in $holder object to $update.
-   * Assumes $holder points at itself.
-   * Asserts $holder is in from-space.
-   * Asserts $update is in to-space.
-   */
-  static inline oop try_update_forwardee(oop obj, oop update);
-
-  /* Sets raw value for forwardee slot.
-   * THIS IS DANGEROUS: USERS HAVE TO INITIALIZE/SET FORWARDEE BACK AFTER THEY ARE DONE.
-   */
-  static inline void set_forwardee_raw(oop obj, HeapWord* update);
-
   /* Returns the raw value from forwardee slot.
    */
   static inline HeapWord* get_forwardee_raw(oop obj);
@@ -99,8 +42,21 @@
    */
   static inline HeapWord* get_forwardee_raw_unchecked(oop obj);
 
-private:
-  static inline HeapWord** forward_ptr_addr(oop obj);
+  /**
+   * Returns true if the object is forwarded, false otherwise.
+   */
+  static inline bool is_forwarded(oop obj);
+
+  /* Tries to atomically update forwardee in $holder object to $update.
+   * Assumes $holder points at itself.
+   * Asserts $holder is in from-space.
+   * Asserts $update is in to-space.
+   *
+   * Returns the new object 'update' upon success, or
+   * the new forwardee that a competing thread installed.
+   */
+  static inline oop try_update_forwardee(oop obj, oop update);
+
 };
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahForwarding.inline.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahForwarding.inline.hpp	Thu May 30 19:49:55 2019 +0200
@@ -26,40 +26,45 @@
 
 #include "gc/shenandoah/shenandoahAsserts.hpp"
 #include "gc/shenandoah/shenandoahForwarding.hpp"
+#include "oops/markOop.inline.hpp"
 #include "runtime/atomic.hpp"
 
-inline HeapWord** ShenandoahForwarding::forward_ptr_addr(oop obj) {
-  return (HeapWord**)((HeapWord*) obj + word_offset());
-}
-
-inline void ShenandoahForwarding::initialize(oop obj) {
-  shenandoah_assert_in_heap(NULL, obj);
-  *forward_ptr_addr(obj) = (HeapWord*) obj;
-}
-
-inline void ShenandoahForwarding::set_forwardee_raw(oop obj, HeapWord* update) {
-  shenandoah_assert_in_heap(NULL, obj);
-  *forward_ptr_addr(obj) = update;
-}
-
 inline HeapWord* ShenandoahForwarding::get_forwardee_raw(oop obj) {
   shenandoah_assert_in_heap(NULL, obj);
-  return *forward_ptr_addr(obj);
+  return get_forwardee_raw_unchecked(obj);
 }
 
 inline HeapWord* ShenandoahForwarding::get_forwardee_raw_unchecked(oop obj) {
-  return *forward_ptr_addr(obj);
+  markOop mark = obj->mark_raw();
+  if (mark->is_marked()) {
+    return (HeapWord*) mark->clear_lock_bits();
+  } else {
+    return (HeapWord*) obj;
+  }
 }
 
 inline oop ShenandoahForwarding::get_forwardee(oop obj) {
   shenandoah_assert_correct(NULL, obj);
-  return oop(*forward_ptr_addr(obj));
+  return oop(get_forwardee_raw_unchecked(obj));
+}
+
+inline bool ShenandoahForwarding::is_forwarded(oop obj) {
+  return obj->mark_raw()->is_marked();
 }
 
 inline oop ShenandoahForwarding::try_update_forwardee(oop obj, oop update) {
-  oop result = (oop) Atomic::cmpxchg(update, (oop*)forward_ptr_addr(obj), obj);
-  shenandoah_assert_correct_except(NULL, obj, !oopDesc::equals_raw(result, obj));
-  return result;
+  markOop old_mark = obj->mark_raw();
+  if (old_mark->is_marked()) {
+    return (oop) old_mark->clear_lock_bits();
+  }
+
+  markOop new_mark = markOopDesc::encode_pointer_as_mark(update);
+  markOop prev_mark = obj->cas_set_mark_raw(new_mark, old_mark);
+  if (prev_mark == old_mark) {
+    return update;
+  } else {
+    return (oop) prev_mark->clear_lock_bits();
+  }
 }
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_INLINE_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu May 30 19:49:55 2019 +0200
@@ -34,7 +34,6 @@
 
 #include "gc/shenandoah/shenandoahAllocTracker.hpp"
 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
-#include "gc/shenandoah/shenandoahForwarding.hpp"
 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
@@ -139,8 +138,6 @@
 };
 
 jint ShenandoahHeap::initialize() {
-  ShenandoahForwarding::initial_checks();
-
   initialize_heuristics();
 
   //
@@ -876,49 +873,6 @@
   return _free_set->allocate(req, in_new_region);
 }
 
-class ShenandoahMemAllocator : public MemAllocator {
-private:
-  MemAllocator& _initializer;
-public:
-  ShenandoahMemAllocator(MemAllocator& initializer, Klass* klass, size_t word_size, Thread* thread) :
-  MemAllocator(klass, word_size + ShenandoahForwarding::word_size(), thread),
-    _initializer(initializer) {}
-
-protected:
-  virtual HeapWord* mem_allocate(Allocation& allocation) const {
-    HeapWord* result = MemAllocator::mem_allocate(allocation);
-    // Initialize brooks-pointer
-    if (result != NULL) {
-      result += ShenandoahForwarding::word_size();
-      ShenandoahForwarding::initialize(oop(result));
-      assert(! ShenandoahHeap::heap()->in_collection_set(result), "never allocate in targetted region");
-    }
-    return result;
-  }
-
-  virtual oop initialize(HeapWord* mem) const {
-     return _initializer.initialize(mem);
-  }
-};
-
-oop ShenandoahHeap::obj_allocate(Klass* klass, int size, TRAPS) {
-  ObjAllocator initializer(klass, size, THREAD);
-  ShenandoahMemAllocator allocator(initializer, klass, size, THREAD);
-  return allocator.allocate();
-}
-
-oop ShenandoahHeap::array_allocate(Klass* klass, int size, int length, bool do_zero, TRAPS) {
-  ObjArrayAllocator initializer(klass, size, length, do_zero, THREAD);
-  ShenandoahMemAllocator allocator(initializer, klass, size, THREAD);
-  return allocator.allocate();
-}
-
-oop ShenandoahHeap::class_allocate(Klass* klass, int size, TRAPS) {
-  ClassAllocator initializer(klass, size, THREAD);
-  ShenandoahMemAllocator allocator(initializer, klass, size, THREAD);
-  return allocator.allocate();
-}
-
 HeapWord* ShenandoahHeap::mem_allocate(size_t size,
                                         bool*  gc_overhead_limit_was_exceeded) {
   ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared(size);
@@ -961,15 +915,6 @@
   return NULL;
 }
 
-void ShenandoahHeap::fill_with_dummy_object(HeapWord* start, HeapWord* end, bool zap) {
-  HeapWord* obj = tlab_post_allocation_setup(start);
-  CollectedHeap::fill_with_object(obj, end);
-}
-
-size_t ShenandoahHeap::min_dummy_object_size() const {
-  return CollectedHeap::min_dummy_object_size() + ShenandoahForwarding::word_size();
-}
-
 class ShenandoahConcurrentEvacuateRegionObjectClosure : public ObjectClosure {
 private:
   ShenandoahHeap* const _heap;
@@ -980,7 +925,7 @@
 
   void do_object(oop p) {
     shenandoah_assert_marked(NULL, p);
-    if (oopDesc::equals_raw(p, ShenandoahBarrierSet::resolve_forwarded_not_null(p))) {
+    if (!p->is_forwarded()) {
       _heap->evacuate_object(p, _thread);
     }
   }
@@ -1060,8 +1005,8 @@
 void ShenandoahHeap::trash_humongous_region_at(ShenandoahHeapRegion* start) {
   assert(start->is_humongous_start(), "reclaim regions starting with the first one");
 
-  oop humongous_obj = oop(start->bottom() + ShenandoahForwarding::word_size());
-  size_t size = humongous_obj->size() + ShenandoahForwarding::word_size();
+  oop humongous_obj = oop(start->bottom());
+  size_t size = humongous_obj->size();
   size_t required_regions = ShenandoahHeapRegion::required_regions(size * HeapWordSize);
   size_t index = start->region_number() + required_regions - 1;
 
@@ -1874,13 +1819,6 @@
   set_gc_state_mask(EVACUATION, in_progress);
 }
 
-HeapWord* ShenandoahHeap::tlab_post_allocation_setup(HeapWord* obj) {
-  // Initialize Brooks pointer for the next object
-  HeapWord* result = obj + ShenandoahForwarding::word_size();
-  ShenandoahForwarding::initialize(oop(result));
-  return result;
-}
-
 void ShenandoahHeap::ref_processing_init() {
   assert(_max_workers > 0, "Sanity");
 
@@ -2853,11 +2791,3 @@
     }
   }
 }
-
-size_t ShenandoahHeap::obj_size(oop obj) const {
-  return CollectedHeap::obj_size(obj) + ShenandoahForwarding::word_size();
-}
-
-ptrdiff_t ShenandoahHeap::cell_header_size() const {
-  return ShenandoahForwarding::byte_size();
-}
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Thu May 30 19:49:55 2019 +0200
@@ -29,7 +29,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shenandoah/shenandoahAsserts.hpp"
 #include "gc/shenandoah/shenandoahAllocRequest.hpp"
-#include "gc/shenandoah/shenandoahHeapLock.hpp"
+#include "gc/shenandoah/shenandoahLock.hpp"
 #include "gc/shenandoah/shenandoahEvacOOMHandler.hpp"
 #include "gc/shenandoah/shenandoahSharedVariables.hpp"
 #include "services/memoryManager.hpp"
@@ -103,6 +103,8 @@
 };
 #endif
 
+typedef ShenandoahLock    ShenandoahHeapLock;
+typedef ShenandoahLocker  ShenandoahHeapLocker;
 
 // Shenandoah GC is low-pause concurrent GC that uses Brooks forwarding pointers
 // to encode forwarding data. See BrooksPointer for details on forwarding data encoding.
@@ -520,9 +522,6 @@
 
   bool is_in(const void* p) const;
 
-  size_t obj_size(oop obj) const;
-  virtual ptrdiff_t cell_header_size() const;
-
   void collect(GCCause::Cause cause);
   void do_full_collection(bool clear_all_soft_refs);
 
@@ -576,10 +575,6 @@
                                                size_t size,
                                                Metaspace::MetadataType mdtype);
 
-  oop obj_allocate(Klass* klass, int size, TRAPS);
-  oop array_allocate(Klass* klass, int size, int length, bool do_zero, TRAPS);
-  oop class_allocate(Klass* klass, int size, TRAPS);
-
   void notify_mutator_alloc_words(size_t words, bool waste);
 
   // Shenandoah supports TLAB allocation
@@ -591,10 +586,6 @@
   size_t max_tlab_size() const;
   size_t tlab_used(Thread* ignored) const;
 
-  HeapWord* tlab_post_allocation_setup(HeapWord* obj);
-  void fill_with_dummy_object(HeapWord* start, HeapWord* end, bool zap);
-  size_t min_dummy_object_size() const;
-
   void resize_tlabs();
 
   void ensure_parsability(bool retire_tlabs);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp	Thu May 30 19:49:55 2019 +0200
@@ -235,51 +235,46 @@
 
   assert(ShenandoahThreadLocalData::is_evac_allowed(thread), "must be enclosed in oom-evac scope");
 
-  size_t size_no_fwdptr = (size_t) p->size();
-  size_t size_with_fwdptr = size_no_fwdptr + ShenandoahForwarding::word_size();
+  size_t size = p->size();
 
   assert(!heap_region_containing(p)->is_humongous(), "never evacuate humongous objects");
 
   bool alloc_from_gclab = true;
-  HeapWord* filler = NULL;
+  HeapWord* copy = NULL;
 
 #ifdef ASSERT
   if (ShenandoahOOMDuringEvacALot &&
       (os::random() & 1) == 0) { // Simulate OOM every ~2nd slow-path call
-        filler = NULL;
+        copy = NULL;
   } else {
 #endif
     if (UseTLAB) {
-      filler = allocate_from_gclab(thread, size_with_fwdptr);
+      copy = allocate_from_gclab(thread, size);
     }
-    if (filler == NULL) {
-      ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared_gc(size_with_fwdptr);
-      filler = allocate_memory(req);
+    if (copy == NULL) {
+      ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared_gc(size);
+      copy = allocate_memory(req);
       alloc_from_gclab = false;
     }
 #ifdef ASSERT
   }
 #endif
 
-  if (filler == NULL) {
-    control_thread()->handle_alloc_failure_evac(size_with_fwdptr);
+  if (copy == NULL) {
+    control_thread()->handle_alloc_failure_evac(size);
 
     _oom_evac_handler.handle_out_of_memory_during_evacuation();
 
     return ShenandoahBarrierSet::resolve_forwarded(p);
   }
 
-  // Copy the object and initialize its forwarding ptr:
-  HeapWord* copy = filler + ShenandoahForwarding::word_size();
-  oop copy_val = oop(copy);
-
-  Copy::aligned_disjoint_words((HeapWord*) p, copy, size_no_fwdptr);
-  ShenandoahForwarding::initialize(oop(copy));
+  // Copy the object:
+  Copy::aligned_disjoint_words((HeapWord*) p, copy, size);
 
   // Try to install the new forwarding pointer.
+  oop copy_val = oop(copy);
   oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val);
-
-  if (oopDesc::equals_raw(result, p)) {
+  if (oopDesc::equals_raw(result, copy_val)) {
     // Successfully evacuated. Our copy is now the public one!
     shenandoah_assert_correct(NULL, copy_val);
     return copy_val;
@@ -296,11 +291,11 @@
     // have to explicitly overwrite the copy with the filler object. With that overwrite,
     // we have to keep the fwdptr initialized and pointing to our (stale) copy.
     if (alloc_from_gclab) {
-      ShenandoahThreadLocalData::gclab(thread)->undo_allocation(filler, size_with_fwdptr);
+      ShenandoahThreadLocalData::gclab(thread)->undo_allocation(copy, size);
     } else {
-      fill_with_object(copy, size_no_fwdptr);
+      fill_with_object(copy, size);
+      shenandoah_assert_correct(NULL, copy_val);
     }
-    shenandoah_assert_correct(NULL, copy_val);
     shenandoah_assert_correct(NULL, result);
     return result;
   }
@@ -371,7 +366,6 @@
 
 template<class T>
 inline void ShenandoahHeap::marked_object_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit) {
-  assert(ShenandoahForwarding::word_offset() < 0, "skip_delta calculation below assumes the forwarding ptr is before obj");
   assert(! region->is_humongous_continuation(), "no humongous continuation regions here");
 
   ShenandoahMarkingContext* const ctx = complete_marking_context();
@@ -380,10 +374,9 @@
   MarkBitMap* mark_bit_map = ctx->mark_bit_map();
   HeapWord* tams = ctx->top_at_mark_start(region);
 
-  size_t skip_bitmap_delta = ShenandoahForwarding::word_size() + 1;
-  size_t skip_objsize_delta = ShenandoahForwarding::word_size() /* + actual obj.size() below */;
-  HeapWord* start = region->bottom() + ShenandoahForwarding::word_size();
-  HeapWord* end = MIN2(tams + ShenandoahForwarding::word_size(), region->end());
+  size_t skip_bitmap_delta = 1;
+  HeapWord* start = region->bottom();
+  HeapWord* end = MIN2(tams, region->end());
 
   // Step 1. Scan below the TAMS based on bitmap data.
   HeapWord* limit_bitmap = MIN2(limit, tams);
@@ -413,7 +406,7 @@
     do {
       avail = 0;
       for (int c = 0; (c < dist) && (cb < limit_bitmap); c++) {
-        Prefetch::read(cb, ShenandoahForwarding::byte_offset());
+        Prefetch::read(cb, oopDesc::mark_offset_in_bytes());
         slots[avail++] = cb;
         cb += skip_bitmap_delta;
         if (cb < limit_bitmap) {
@@ -448,16 +441,16 @@
   // Step 2. Accurate size-based traversal, happens past the TAMS.
   // This restarts the scan at TAMS, which makes sure we traverse all objects,
   // regardless of what happened at Step 1.
-  HeapWord* cs = tams + ShenandoahForwarding::word_size();
+  HeapWord* cs = tams;
   while (cs < limit) {
-    assert (cs > tams,  "only objects past TAMS here: "   PTR_FORMAT " (" PTR_FORMAT ")", p2i(cs), p2i(tams));
+    assert (cs >= tams, "only objects past TAMS here: "   PTR_FORMAT " (" PTR_FORMAT ")", p2i(cs), p2i(tams));
     assert (cs < limit, "only objects below limit here: " PTR_FORMAT " (" PTR_FORMAT ")", p2i(cs), p2i(limit));
     oop obj = oop(cs);
     assert(oopDesc::is_oop(obj), "sanity");
     assert(ctx->is_marked(obj), "object expected to be marked");
     int size = obj->size();
     cl->do_object(obj);
-    cs += size + skip_objsize_delta;
+    cs += size;
   }
 }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapLock.hpp	Thu May 23 22:12:31 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
- *
- * This code is free software; you can redistribute 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_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP
-#define SHARE_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP
-
-#include "memory/allocation.hpp"
-#include "runtime/thread.hpp"
-
-class ShenandoahHeapLock  {
-private:
-  enum LockState { unlocked = 0, locked = 1 };
-
-  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile int));
-  volatile int _state;
-  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile Thread*));
-  volatile Thread* _owner;
-  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, 0);
-
-public:
-  ShenandoahHeapLock() : _state(unlocked), _owner(NULL) {};
-
-  void lock() {
-    Thread::SpinAcquire(&_state, "Shenandoah Heap Lock");
-#ifdef ASSERT
-    assert(_state == locked, "must be locked");
-    assert(_owner == NULL, "must not be owned");
-    _owner = Thread::current();
-#endif
-  }
-
-  void unlock() {
-#ifdef ASSERT
-    assert (_owner == Thread::current(), "sanity");
-    _owner = NULL;
-#endif
-    Thread::SpinRelease(&_state);
-  }
-
-#ifdef ASSERT
-  void assert_owned_by_current_thread() {
-    assert(_state == locked, "must be locked");
-    assert(_owner == Thread::current(), "must be owned by current thread");
-  }
-
-  void assert_not_owned_by_current_thread() {
-    assert(_owner != Thread::current(), "must be not owned by current thread");
-  }
-
-  void assert_owned_by_current_thread_or_safepoint() {
-    Thread* thr = Thread::current();
-    assert((_state == locked && _owner == thr) ||
-           (SafepointSynchronize::is_at_safepoint() && thr->is_VM_thread()),
-           "must own heap lock or by VM thread at safepoint");
-  }
-#endif
-};
-
-class ShenandoahHeapLocker : public StackObj {
-private:
-  ShenandoahHeapLock* _lock;
-public:
-  ShenandoahHeapLocker(ShenandoahHeapLock* lock) {
-    _lock = lock;
-    _lock->lock();
-  }
-
-  ~ShenandoahHeapLocker() {
-    _lock->unlock();
-  }
-};
-
-#endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp	Thu May 30 19:49:55 2019 +0200
@@ -23,7 +23,6 @@
 
 #include "precompiled.hpp"
 #include "memory/allocation.hpp"
-#include "gc/shenandoah/shenandoahForwarding.hpp"
 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
@@ -453,12 +452,12 @@
 
 void ShenandoahHeapRegion::oop_iterate_objects(OopIterateClosure* blk) {
   assert(! is_humongous(), "no humongous region here");
-  HeapWord* obj_addr = bottom() + ShenandoahForwarding::word_size();
+  HeapWord* obj_addr = bottom();
   HeapWord* t = top();
   // Could call objects iterate, but this is easier.
   while (obj_addr < t) {
     oop obj = oop(obj_addr);
-    obj_addr += obj->oop_iterate_size(blk) + ShenandoahForwarding::word_size();
+    obj_addr += obj->oop_iterate_size(blk);
   }
 }
 
@@ -467,7 +466,7 @@
   // Find head.
   ShenandoahHeapRegion* r = humongous_start_region();
   assert(r->is_humongous_start(), "need humongous head here");
-  oop obj = oop(r->bottom() + ShenandoahForwarding::word_size());
+  oop obj = oop(r->bottom());
   obj->oop_iterate(blk, MemRegion(bottom(), top()));
 }
 
@@ -506,11 +505,11 @@
   if (p >= top()) {
     return top();
   } else {
-    HeapWord* last = bottom() + ShenandoahForwarding::word_size();
+    HeapWord* last = bottom();
     HeapWord* cur = last;
     while (cur <= p) {
       last = cur;
-      cur += oop(cur)->size() + ShenandoahForwarding::word_size();
+      cur += oop(cur)->size();
     }
     shenandoah_assert_correct(NULL, oop(last));
     return last;
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp	Thu May 30 19:49:55 2019 +0200
@@ -24,7 +24,6 @@
 #include "precompiled.hpp"
 
 #include "gc/shared/gcCause.hpp"
-#include "gc/shenandoah/shenandoahForwarding.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.inline.hpp"
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
@@ -164,7 +163,7 @@
       // Reclaim humongous regions here, and count them as the immediate garbage
 #ifdef ASSERT
       bool reg_live = region->has_live();
-      bool bm_live = ctx->is_marked(oop(region->bottom() + ShenandoahForwarding::word_size()));
+      bool bm_live = ctx->is_marked(oop(region->bottom()));
       assert(reg_live == bm_live,
              "Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: " SIZE_FORMAT,
              BOOL_TO_STR(reg_live), BOOL_TO_STR(bm_live), region->get_live_data_words());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp	Thu May 30 19:49:55 2019 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute 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_SHENANDOAH_SHENANDOAHLOCK_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHLOCK_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/thread.hpp"
+
+class ShenandoahLock  {
+private:
+  enum LockState { unlocked = 0, locked = 1 };
+
+  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile int));
+  volatile int _state;
+  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile Thread*));
+  volatile Thread* _owner;
+  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, 0);
+
+public:
+  ShenandoahLock() : _state(unlocked), _owner(NULL) {};
+
+  void lock() {
+    Thread::SpinAcquire(&_state, "Shenandoah Heap Lock");
+#ifdef ASSERT
+    assert(_state == locked, "must be locked");
+    assert(_owner == NULL, "must not be owned");
+    _owner = Thread::current();
+#endif
+  }
+
+  void unlock() {
+#ifdef ASSERT
+    assert (_owner == Thread::current(), "sanity");
+    _owner = NULL;
+#endif
+    Thread::SpinRelease(&_state);
+  }
+
+#ifdef ASSERT
+  void assert_owned_by_current_thread() {
+    assert(_state == locked, "must be locked");
+    assert(_owner == Thread::current(), "must be owned by current thread");
+  }
+
+  void assert_not_owned_by_current_thread() {
+    assert(_owner != Thread::current(), "must be not owned by current thread");
+  }
+
+  void assert_owned_by_current_thread_or_safepoint() {
+    Thread* thr = Thread::current();
+    assert((_state == locked && _owner == thr) ||
+           (SafepointSynchronize::is_at_safepoint() && thr->is_VM_thread()),
+           "must own heap lock or by VM thread at safepoint");
+  }
+#endif
+};
+
+class ShenandoahLocker : public StackObj {
+private:
+  ShenandoahLock* const _lock;
+public:
+  ShenandoahLocker(ShenandoahLock* lock) : _lock(lock) {
+    if (_lock != NULL) {
+      _lock->lock();
+    }
+  }
+
+  ~ShenandoahLocker() {
+    if (_lock != NULL) {
+      _lock->unlock();
+    }
+  }
+};
+
+#endif // SHARE_GC_SHENANDOAH_SHENANDOAHLOCK_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Thu May 30 19:49:55 2019 +0200
@@ -25,6 +25,7 @@
 
 #include "code/codeCache.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
+#include "gc/shared/preservedMarks.inline.hpp"
 #include "gc/shenandoah/shenandoahForwarding.inline.hpp"
 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
@@ -46,11 +47,16 @@
 #include "memory/universe.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/biasedLocking.hpp"
 #include "runtime/thread.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/growableArray.hpp"
 #include "gc/shared/workgroup.hpp"
 
+ShenandoahMarkCompact::ShenandoahMarkCompact() :
+  _gc_timer(NULL),
+  _preserved_marks(new PreservedMarksSet(true)) {}
+
 void ShenandoahMarkCompact::initialize(GCTimer* gc_timer) {
   _gc_timer = gc_timer;
 }
@@ -121,6 +127,10 @@
 
     // e. Set back forwarded objects bit back, in case some steps above dropped it.
     heap->set_has_forwarded_objects(has_forwarded_objects);
+
+    // The rest of prologue:
+    BiasedLocking::preserve_marks();
+    _preserved_marks->init(heap->workers()->active_workers());
   }
 
   heap->make_parsable(true);
@@ -159,6 +169,16 @@
     phase4_compact_objects(worker_slices);
   }
 
+  {
+    // Epilogue
+    SharedRestorePreservedMarksTaskExecutor exec(heap->workers());
+    _preserved_marks->restore(&exec);
+    BiasedLocking::restore_marks();
+    _preserved_marks->reclaim();
+
+    JvmtiExport::gc_epilogue();
+  }
+
   // Resize metaspace
   MetaspaceGC::compute_new_size();
 
@@ -168,8 +188,6 @@
   }
   FREE_C_HEAP_ARRAY(ShenandoahHeapRegionSet*, worker_slices);
 
-  JvmtiExport::gc_epilogue();
-
   heap->set_full_gc_move_in_progress(false);
   heap->set_full_gc_in_progress(false);
 
@@ -230,6 +248,7 @@
 
 class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure {
 private:
+  PreservedMarks*          const _preserved_marks;
   ShenandoahHeap*          const _heap;
   GrowableArray<ShenandoahHeapRegion*>& _empty_regions;
   int _empty_regions_pos;
@@ -238,7 +257,10 @@
   HeapWord* _compact_point;
 
 public:
-  ShenandoahPrepareForCompactionObjectClosure(GrowableArray<ShenandoahHeapRegion*>& empty_regions, ShenandoahHeapRegion* to_region) :
+  ShenandoahPrepareForCompactionObjectClosure(PreservedMarks* preserved_marks,
+                                              GrowableArray<ShenandoahHeapRegion*>& empty_regions,
+                                              ShenandoahHeapRegion* to_region) :
+    _preserved_marks(preserved_marks),
     _heap(ShenandoahHeap::heap()),
     _empty_regions(empty_regions),
     _empty_regions_pos(0),
@@ -268,7 +290,7 @@
     assert(_heap->complete_marking_context()->is_marked(p), "must be marked");
     assert(!_heap->complete_marking_context()->allocated_after_mark_start((HeapWord*) p), "must be truly marked");
 
-    size_t obj_size = p->size() + ShenandoahForwarding::word_size();
+    size_t obj_size = p->size();
     if (_compact_point + obj_size > _to_region->end()) {
       finish_region();
 
@@ -291,13 +313,15 @@
     // Object fits into current region, record new location:
     assert(_compact_point + obj_size <= _to_region->end(), "must fit");
     shenandoah_assert_not_forwarded(NULL, p);
-    ShenandoahForwarding::set_forwardee_raw(p, _compact_point + ShenandoahForwarding::word_size());
+    _preserved_marks->push_if_necessary(p, p->mark_raw());
+    p->forward_to(oop(_compact_point));
     _compact_point += obj_size;
   }
 };
 
 class ShenandoahPrepareForCompactionTask : public AbstractGangTask {
 private:
+  PreservedMarksSet*        const _preserved_marks;
   ShenandoahHeap*           const _heap;
   ShenandoahHeapRegionSet** const _worker_slices;
   ShenandoahRegionIterator        _heap_regions;
@@ -320,8 +344,9 @@
   }
 
 public:
-  ShenandoahPrepareForCompactionTask(ShenandoahHeapRegionSet** worker_slices) :
+  ShenandoahPrepareForCompactionTask(PreservedMarksSet* preserved_marks, ShenandoahHeapRegionSet** worker_slices) :
     AbstractGangTask("Shenandoah Prepare For Compaction Task"),
+    _preserved_marks(preserved_marks),
     _heap(ShenandoahHeap::heap()), _worker_slices(worker_slices) {
   }
 
@@ -337,7 +362,7 @@
     // Remember empty regions and reuse them as needed.
     ResourceMark rm;
     GrowableArray<ShenandoahHeapRegion*> empty_regions((int)_heap->num_regions());
-    ShenandoahPrepareForCompactionObjectClosure cl(empty_regions, from_region);
+    ShenandoahPrepareForCompactionObjectClosure cl(_preserved_marks->get(worker_id), empty_regions, from_region);
     while (from_region != NULL) {
       cl.set_from_region(from_region);
       if (from_region->has_live()) {
@@ -377,8 +402,8 @@
   size_t to_begin = heap->num_regions();
   size_t to_end = heap->num_regions();
 
-  for (size_t c = heap->num_regions() - 1; c > 0; c--) {
-    ShenandoahHeapRegion *r = heap->get_region(c);
+  for (size_t c = heap->num_regions(); c > 0; c--) {
+    ShenandoahHeapRegion *r = heap->get_region(c - 1);
     if (r->is_humongous_continuation() || (r->new_top() == r->bottom())) {
       // To-region candidate: record this, and continue scan
       to_begin = r->region_number();
@@ -387,15 +412,16 @@
 
     if (r->is_humongous_start() && r->is_move_allowed()) {
       // From-region candidate: movable humongous region
-      oop old_obj = oop(r->bottom() + ShenandoahForwarding::word_size());
-      size_t words_size = old_obj->size() + ShenandoahForwarding::word_size();
+      oop old_obj = oop(r->bottom());
+      size_t words_size = old_obj->size();
       size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize);
 
       size_t start = to_end - num_regions;
 
       if (start >= to_begin && start != r->region_number()) {
         // Fits into current window, and the move is non-trivial. Record the move then, and continue scan.
-        ShenandoahForwarding::set_forwardee_raw(old_obj, heap->get_region(start)->bottom() + ShenandoahForwarding::word_size());
+        _preserved_marks->get(0)->push_if_necessary(old_obj, old_obj->mark_raw());
+        old_obj->forward_to(oop(heap->get_region(start)->bottom()));
         to_end = start;
         continue;
       }
@@ -443,7 +469,7 @@
 
   void heap_region_do(ShenandoahHeapRegion* r) {
     if (r->is_humongous_start()) {
-      oop humongous_obj = oop(r->bottom() + ShenandoahForwarding::word_size());
+      oop humongous_obj = oop(r->bottom());
       if (!_ctx->is_marked(humongous_obj)) {
         assert(!r->has_live(),
                "Region " SIZE_FORMAT " is not marked, should not have live", r->region_number());
@@ -484,7 +510,7 @@
   // Compute the new addresses for regular objects
   {
     ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_calculate_addresses_regular);
-    ShenandoahPrepareForCompactionTask prepare_task(worker_slices);
+    ShenandoahPrepareForCompactionTask prepare_task(_preserved_marks, worker_slices);
     heap->workers()->run_task(&prepare_task);
   }
 
@@ -506,8 +532,10 @@
     if (!CompressedOops::is_null(o)) {
       oop obj = CompressedOops::decode_not_null(o);
       assert(_ctx->is_marked(obj), "must be marked");
-      oop forw = oop(ShenandoahForwarding::get_forwardee_raw(obj));
-      RawAccess<IS_NOT_NULL>::oop_store(p, forw);
+      if (obj->is_forwarded()) {
+        oop forw = obj->forwardee();
+        RawAccess<IS_NOT_NULL>::oop_store(p, forw);
+      }
     }
   }
 
@@ -531,7 +559,6 @@
   }
   void do_object(oop p) {
     assert(_heap->complete_marking_context()->is_marked(p), "must be marked");
-    HeapWord* forw = ShenandoahForwarding::get_forwardee_raw(p);
     p->oop_iterate(&_cl);
   }
 };
@@ -562,15 +589,17 @@
 class ShenandoahAdjustRootPointersTask : public AbstractGangTask {
 private:
   ShenandoahRootAdjuster* _rp;
-
+  PreservedMarksSet* _preserved_marks;
 public:
-  ShenandoahAdjustRootPointersTask(ShenandoahRootAdjuster* rp) :
+  ShenandoahAdjustRootPointersTask(ShenandoahRootAdjuster* rp, PreservedMarksSet* preserved_marks) :
     AbstractGangTask("Shenandoah Adjust Root Pointers Task"),
-    _rp(rp) {}
+    _rp(rp),
+    _preserved_marks(preserved_marks) {}
 
   void work(uint worker_id) {
     ShenandoahAdjustPointersClosure cl;
     _rp->roots_do(worker_id, &cl);
+    _preserved_marks->get(worker_id)->adjust_during_full_gc();
   }
 };
 
@@ -587,7 +616,7 @@
     DerivedPointerTable::clear();
 #endif
     ShenandoahRootAdjuster rp(nworkers, ShenandoahPhaseTimings::full_gc_roots);
-    ShenandoahAdjustRootPointersTask task(&rp);
+    ShenandoahAdjustRootPointersTask task(&rp, _preserved_marks);
     workers->run_task(&task);
 #if COMPILER2_OR_JVMCI
     DerivedPointerTable::update_pointers();
@@ -610,13 +639,13 @@
   void do_object(oop p) {
     assert(_heap->complete_marking_context()->is_marked(p), "must be marked");
     size_t size = (size_t)p->size();
-    HeapWord* compact_to = ShenandoahForwarding::get_forwardee_raw(p);
-    HeapWord* compact_from = (HeapWord*) p;
-    if (compact_from != compact_to) {
+    if (p->is_forwarded()) {
+      HeapWord* compact_from = (HeapWord*) p;
+      HeapWord* compact_to = (HeapWord*) p->forwardee();
       Copy::aligned_conjoint_words(compact_from, compact_to, size);
+      oop new_obj = oop(compact_to);
+      new_obj->init_mark_raw();
     }
-    oop new_obj = oop(compact_to);
-    ShenandoahForwarding::initialize(new_obj);
   }
 };
 
@@ -707,31 +736,30 @@
 
   ShenandoahHeap* heap = ShenandoahHeap::heap();
 
-  for (size_t c = heap->num_regions() - 1; c > 0; c--) {
-    ShenandoahHeapRegion* r = heap->get_region(c);
+  for (size_t c = heap->num_regions(); c > 0; c--) {
+    ShenandoahHeapRegion* r = heap->get_region(c - 1);
     if (r->is_humongous_start()) {
-      oop old_obj = oop(r->bottom() + ShenandoahForwarding::word_size());
-      size_t words_size = old_obj->size() + ShenandoahForwarding::word_size();
+      oop old_obj = oop(r->bottom());
+      if (!old_obj->is_forwarded()) {
+        // No need to move the object, it stays at the same slot
+        continue;
+      }
+      size_t words_size = old_obj->size();
       size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize);
 
       size_t old_start = r->region_number();
       size_t old_end   = old_start + num_regions - 1;
-      size_t new_start = heap->heap_region_index_containing(ShenandoahForwarding::get_forwardee_raw(old_obj));
+      size_t new_start = heap->heap_region_index_containing(old_obj->forwardee());
       size_t new_end   = new_start + num_regions - 1;
-
-      if (old_start == new_start) {
-        // No need to move the object, it stays at the same slot
-        continue;
-      }
-
+      assert(old_start != new_start, "must be real move");
       assert (r->is_move_allowed(), "should be movable");
 
       Copy::aligned_conjoint_words(heap->get_region(old_start)->bottom(),
                                    heap->get_region(new_start)->bottom(),
                                    ShenandoahHeapRegion::region_size_words()*num_regions);
 
-      oop new_obj = oop(heap->get_region(new_start)->bottom() + ShenandoahForwarding::word_size());
-      ShenandoahForwarding::initialize(new_obj);
+      oop new_obj = oop(heap->get_region(new_start)->bottom());
+      new_obj->init_mark_raw();
 
       {
         for (size_t c = old_start; c <= old_end; c++) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.hpp	Thu May 30 19:49:55 2019 +0200
@@ -49,12 +49,19 @@
  * where it does sliding compaction, without interfering with other threads.
  */
 
+class PreservedMarksSet;
+
 class ShenandoahMarkCompact : public CHeapObj<mtGC> {
+  friend class ShenandoahPrepareForCompactionObjectClosure;
 private:
   GCTimer* _gc_timer;
 
+  PreservedMarksSet* _preserved_marks;
+
 public:
+  ShenandoahMarkCompact();
   void initialize(GCTimer* gc_timer);
+
   void do_it(GCCause::Cause gc_cause);
 
 private:
@@ -65,7 +72,6 @@
 
   void calculate_target_humongous_objects();
   void compact_humongous_objects();
-
 };
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHMARKCOMPACT_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Thu May 30 19:49:55 2019 +0200
@@ -27,6 +27,7 @@
 #include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
+#include "gc/shenandoah/shenandoahUtils.hpp"
 #include "memory/resourceArea.hpp"
 
 template <typename IsAlive, typename KeepAlive>
@@ -90,9 +91,10 @@
 
 template <typename ITR>
 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
-  assert(!ShenandoahHeap::heap()->unload_classes() ||
+  assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
+         !ShenandoahHeap::heap()->unload_classes() ||
           ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc(),
-          "No class unloading or traversal GC");
+          "Expect class unloading or traversal when Shenandoah cycle is running");
   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
   ResourceMark rm;
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp	Thu May 30 19:49:55 2019 +0200
@@ -59,7 +59,7 @@
   }
 
   if (verify(CLDGRoots)) {
-    CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
+    CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
     ClassLoaderDataGraph::cld_do(&clds);
   }
 
@@ -88,3 +88,49 @@
     Threads::possibly_parallel_oops_do(false, oops, &blobs);
   }
 }
+
+void ShenandoahRootVerifier::roots_do(OopClosure* oops) {
+  CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
+  CodeCache::blobs_do(&blobs);
+
+  CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
+  ClassLoaderDataGraph::cld_do(&clds);
+
+  Universe::oops_do(oops);
+  Management::oops_do(oops);
+  JvmtiExport::oops_do(oops);
+  JNIHandles::oops_do(oops);
+  ObjectSynchronizer::oops_do(oops);
+  SystemDictionary::oops_do(oops);
+
+  AlwaysTrueClosure always_true;
+  WeakProcessor::weak_oops_do(&always_true, oops);
+
+  if (ShenandoahStringDedup::is_enabled()) {
+    ShenandoahStringDedup::oops_do_slow(oops);
+  }
+
+  // Do thread roots the last. This allows verification code to find
+  // any broken objects from those special roots first, not the accidental
+  // dangling reference from the thread root.
+  Threads::possibly_parallel_oops_do(false, oops, &blobs);
+}
+
+void ShenandoahRootVerifier::strong_roots_do(OopClosure* oops) {
+  CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
+
+  CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
+  ClassLoaderDataGraph::roots_cld_do(&clds, NULL);
+
+  Universe::oops_do(oops);
+  Management::oops_do(oops);
+  JvmtiExport::oops_do(oops);
+  JNIHandles::oops_do(oops);
+  ObjectSynchronizer::oops_do(oops);
+  SystemDictionary::oops_do(oops);
+
+  // Do thread roots the last. This allows verification code to find
+  // any broken objects from those special roots first, not the accidental
+  // dangling reference from the thread root.
+  Threads::possibly_parallel_oops_do(false, oops, &blobs);
+}
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp	Thu May 30 19:49:55 2019 +0200
@@ -48,6 +48,9 @@
   void excludes(RootTypes types);
   void oops_do(OopClosure* cl);
 
+  // Used to seed ShenandoahVerifier, do not honor root type filter
+  void roots_do(OopClosure* cl);
+  void strong_roots_do(OopClosure* cl);
 private:
   bool verify(RootTypes type) const;
 };
--- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp	Thu May 30 19:49:55 2019 +0200
@@ -35,7 +35,6 @@
 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
 #include "gc/shenandoah/shenandoahFreeSet.hpp"
-#include "gc/shenandoah/shenandoahForwarding.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
@@ -633,7 +632,7 @@
         bool candidate = traversal_regions->is_in(r) && !r->has_live() && not_allocated;
         if (r->is_humongous_start() && candidate) {
           // Trash humongous.
-          HeapWord* humongous_obj = r->bottom() + ShenandoahForwarding::word_size();
+          HeapWord* humongous_obj = r->bottom();
           assert(!ctx->is_marked(oop(humongous_obj)), "must not be marked");
           r->make_trash_immediate();
           while (i + 1 < num_regions && _heap->get_region(i + 1)->is_humongous_continuation()) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp	Thu May 30 19:49:55 2019 +0200
@@ -138,7 +138,7 @@
           // skip
           break;
         case ShenandoahVerifier::_verify_liveness_complete:
-          Atomic::add(obj->size() + ShenandoahForwarding::word_size(), &_ld[obj_reg->region_number()]);
+          Atomic::add((uint) obj->size(), &_ld[obj_reg->region_number()]);
           // fallthrough for fast failure for un-live regions:
         case ShenandoahVerifier::_verify_liveness_conservative:
           check(ShenandoahAsserts::_safe_oop, obj, obj_reg->has_live(),
@@ -458,7 +458,11 @@
         ShenandoahVerifyOopClosure cl(&stack, _bitmap, _ld,
                                       ShenandoahMessageBuffer("%s, Roots", _label),
                                       _options);
-        _verifier->oops_do(&cl);
+        if (_heap->unload_classes()) {
+          _verifier->strong_roots_do(&cl);
+        } else {
+          _verifier->roots_do(&cl);
+        }
     }
 
     size_t processed = 0;
@@ -529,7 +533,7 @@
 
   virtual void work_humongous(ShenandoahHeapRegion *r, ShenandoahVerifierStack& stack, ShenandoahVerifyOopClosure& cl) {
     size_t processed = 0;
-    HeapWord* obj = r->bottom() + ShenandoahForwarding::word_size();
+    HeapWord* obj = r->bottom();
     if (_heap->complete_marking_context()->is_marked((oop)obj)) {
       verify_and_follow(obj, stack, cl, &processed);
     }
@@ -543,12 +547,12 @@
 
     // Bitmaps, before TAMS
     if (tams > r->bottom()) {
-      HeapWord* start = r->bottom() + ShenandoahForwarding::word_size();
+      HeapWord* start = r->bottom();
       HeapWord* addr = mark_bit_map->get_next_marked_addr(start, tams);
 
       while (addr < tams) {
         verify_and_follow(addr, stack, cl, &processed);
-        addr += ShenandoahForwarding::word_size();
+        addr += 1;
         if (addr < tams) {
           addr = mark_bit_map->get_next_marked_addr(addr, tams);
         }
@@ -558,11 +562,11 @@
     // Size-based, after TAMS
     {
       HeapWord* limit = r->top();
-      HeapWord* addr = tams + ShenandoahForwarding::word_size();
+      HeapWord* addr = tams;
 
       while (addr < limit) {
         verify_and_follow(addr, stack, cl, &processed);
-        addr += oop(addr)->size() + ShenandoahForwarding::word_size();
+        addr += oop(addr)->size();
       }
     }
 
--- a/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp	Thu May 30 19:49:55 2019 +0200
@@ -67,9 +67,14 @@
  private:
   CPUInformationInterface* _cpu_info_interface;
   CPUPerformanceInterface* _cpu_perf_interface;
-  SystemProcessInterface*  _system_process_interface;
+  SystemProcessInterface* _system_process_interface;
   NetworkPerformanceInterface* _network_performance_interface;
 
+  CPUInformationInterface* cpu_info_interface();
+  CPUPerformanceInterface* cpu_perf_interface();
+  SystemProcessInterface* system_process_interface();
+  NetworkPerformanceInterface* network_performance_interface();
+
   JfrOSInterfaceImpl();
   bool initialize();
   ~JfrOSInterfaceImpl();
@@ -90,28 +95,57 @@
    // system processes information
   int system_processes(SystemProcess** system_processes, int* no_of_sys_processes);
 
-  int network_utilization(NetworkInterface** network_interfaces) const;
+  int network_utilization(NetworkInterface** network_interfaces);
 };
 
 JfrOSInterface::JfrOSInterfaceImpl::JfrOSInterfaceImpl() : _cpu_info_interface(NULL),
                                                            _cpu_perf_interface(NULL),
-                                                           _system_process_interface(NULL) {}
+                                                           _system_process_interface(NULL),
+                                                           _network_performance_interface(NULL) {}
+
+template <typename T>
+static T* create_interface() {
+  ResourceMark rm;
+  T* iface = new T();
+  if (iface != NULL) {
+    if (!iface->initialize()) {
+      delete iface;
+      iface = NULL;
+    }
+  }
+  return iface;
+}
+
+CPUInformationInterface* JfrOSInterface::JfrOSInterfaceImpl::cpu_info_interface() {
+  if (_cpu_info_interface == NULL) {
+    _cpu_info_interface = create_interface<CPUInformationInterface>();
+  }
+  return _cpu_info_interface;
+}
+
+CPUPerformanceInterface* JfrOSInterface::JfrOSInterfaceImpl::cpu_perf_interface() {
+  if (_cpu_perf_interface == NULL) {
+    _cpu_perf_interface = create_interface<CPUPerformanceInterface>();
+  }
+  return _cpu_perf_interface;
+}
+
+SystemProcessInterface* JfrOSInterface::JfrOSInterfaceImpl::system_process_interface() {
+  if (_system_process_interface == NULL) {
+    _system_process_interface = create_interface<SystemProcessInterface>();
+  }
+  return _system_process_interface;
+}
+
+NetworkPerformanceInterface* JfrOSInterface::JfrOSInterfaceImpl::network_performance_interface() {
+  if (_network_performance_interface == NULL) {
+    _network_performance_interface = create_interface<NetworkPerformanceInterface>();
+  }
+  return _network_performance_interface;
+}
 
 bool JfrOSInterface::JfrOSInterfaceImpl::initialize() {
-  _cpu_info_interface = new CPUInformationInterface();
-  if (!(_cpu_info_interface != NULL && _cpu_info_interface->initialize())) {
-    return false;
-  }
-  _cpu_perf_interface = new CPUPerformanceInterface();
-  if (!(_cpu_perf_interface != NULL && _cpu_perf_interface->initialize())) {
-    return false;
-  }
-  _system_process_interface = new SystemProcessInterface();
-  if (!(_system_process_interface != NULL && _system_process_interface->initialize())) {
-    return false;
-  }
-  _network_performance_interface = new NetworkPerformanceInterface();
-  return _network_performance_interface != NULL && _network_performance_interface->initialize();
+  return true;
 }
 
 JfrOSInterface::JfrOSInterfaceImpl::~JfrOSInterfaceImpl(void) {
@@ -133,36 +167,43 @@
   }
 }
 
+int JfrOSInterface::JfrOSInterfaceImpl::cpu_information(CPUInformation& cpu_info) {
+  CPUInformationInterface* const iface = cpu_info_interface();
+  return iface == NULL ? OS_ERR : iface->cpu_information(cpu_info);
+}
+
 int JfrOSInterface::JfrOSInterfaceImpl::cpu_load(int which_logical_cpu, double* cpu_load) {
-  return _cpu_perf_interface->cpu_load(which_logical_cpu, cpu_load);
+  CPUPerformanceInterface* const iface = cpu_perf_interface();
+  return iface == NULL ? OS_ERR : iface->cpu_load(which_logical_cpu, cpu_load);
 }
 
 int JfrOSInterface::JfrOSInterfaceImpl::context_switch_rate(double* rate) {
-  return _cpu_perf_interface->context_switch_rate(rate);
+  CPUPerformanceInterface* const iface = cpu_perf_interface();
+  return iface == NULL ? OS_ERR : iface->context_switch_rate(rate);
 }
 
 int JfrOSInterface::JfrOSInterfaceImpl::cpu_load_total_process(double* cpu_load) {
-  return _cpu_perf_interface->cpu_load_total_process(cpu_load);
+  CPUPerformanceInterface* const iface = cpu_perf_interface();
+  return iface == NULL ? OS_ERR : iface->cpu_load_total_process(cpu_load);
 }
 
 int JfrOSInterface::JfrOSInterfaceImpl::cpu_loads_process(double* pjvmUserLoad,
                                                           double* pjvmKernelLoad,
                                                           double* psystemTotal) {
-  return _cpu_perf_interface->cpu_loads_process(pjvmUserLoad, pjvmKernelLoad, psystemTotal);
-}
-
-int JfrOSInterface::JfrOSInterfaceImpl::cpu_information(CPUInformation& cpu_info) {
-  return _cpu_info_interface->cpu_information(cpu_info);
+  CPUPerformanceInterface* const iface = cpu_perf_interface();
+  return iface == NULL ? OS_ERR : iface->cpu_loads_process(pjvmUserLoad, pjvmKernelLoad, psystemTotal);
 }
 
 int JfrOSInterface::JfrOSInterfaceImpl::system_processes(SystemProcess** system_processes, int* no_of_sys_processes) {
   assert(system_processes != NULL, "system_processes pointer is NULL!");
   assert(no_of_sys_processes != NULL, "no_of_sys_processes pointer is NULL!");
-  return _system_process_interface->system_processes(system_processes, no_of_sys_processes);
+  SystemProcessInterface* const iface = system_process_interface();
+  return iface == NULL ? OS_ERR : iface->system_processes(system_processes, no_of_sys_processes);
 }
 
-int JfrOSInterface::JfrOSInterfaceImpl::network_utilization(NetworkInterface** network_interfaces) const {
-  return _network_performance_interface->network_utilization(network_interfaces);
+int JfrOSInterface::JfrOSInterfaceImpl::network_utilization(NetworkInterface** network_interfaces) {
+  NetworkPerformanceInterface* const iface = network_performance_interface();
+  return iface == NULL ? OS_ERR : iface->network_utilization(network_interfaces);
 }
 
 // assigned char* is RESOURCE_HEAP_ALLOCATED
--- a/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp	Thu May 30 19:49:55 2019 +0200
@@ -132,10 +132,6 @@
   OrderAccess::release_store(&_identity, (const void*)NULL);
 }
 
-void JfrBuffer::clear_identity() {
-  _identity = NULL;
-}
-
 bool JfrBuffer::acquired_by(const void* id) const {
   return identity() == id;
 }
--- a/src/hotspot/share/jfr/recorder/storage/jfrBuffer.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/storage/jfrBuffer.hpp	Thu May 30 19:49:55 2019 +0200
@@ -145,8 +145,6 @@
     return _identity;
   }
 
-  void clear_identity();
-
   void acquire(const void* id);
   bool try_acquire(const void* id);
   bool acquired_by(const void* id) const;
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp	Thu May 30 19:49:55 2019 +0200
@@ -312,7 +312,11 @@
 
 static bool insert_full_age_node(JfrAgeNode* age_node, JfrStorageAgeMspace* age_mspace, Thread* thread) {
   assert(JfrBuffer_lock->owned_by_self(), "invariant");
+  assert(age_node != NULL, "invariant");
+  assert(age_node->acquired_by_self(), "invariant");
   assert(age_node->retired_buffer()->retired(), "invariant");
+  age_node->release(); // drop identity claim on age node when inserting to full list
+  assert(age_node->identity() == NULL, "invariant");
   age_mspace->insert_full_head(age_node);
   return true;
 }
@@ -329,8 +333,8 @@
       return false;
     }
   }
+  assert(age_node != NULL, "invariant");
   assert(age_node->acquired_by_self(), "invariant");
-  assert(age_node != NULL, "invariant");
   age_node->set_retired_buffer(buffer);
   control.increment_full();
   return insert_full_age_node(age_node, age_mspace, thread);
@@ -412,6 +416,7 @@
       if (oldest_age_node == NULL) {
         break;
       }
+      assert(oldest_age_node->identity() == NULL, "invariant");
       BufferPtr const buffer = oldest_age_node->retired_buffer();
       assert(buffer->retired(), "invariant");
       discarded_size += buffer->unflushed_size();
@@ -423,7 +428,7 @@
       } else {
         mspace_release_full(oldest_age_node, _age_mspace);
         buffer->reinitialize();
-        buffer->release(); // pusb
+        buffer->release(); // publish
         break;
       }
     }
@@ -637,12 +642,12 @@
   JfrAgeNode* last = NULL;
   while (node != NULL) {
     last = node;
+    assert(node->identity() == NULL, "invariant");
     BufferPtr const buffer = node->retired_buffer();
     assert(buffer != NULL, "invariant");
     assert(buffer->retired(), "invariant");
     processor.process(buffer);
     // at this point, buffer is already live or destroyed
-    node->clear_identity();
     JfrAgeNode* const next = (JfrAgeNode*)node->next();
     if (node->transient()) {
       // detach
--- a/src/hotspot/share/jfr/support/jfrFlush.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/jfr/support/jfrFlush.cpp	Thu May 30 19:49:55 2019 +0200
@@ -62,7 +62,6 @@
 }
 
 void jfr_conditional_flush(JfrEventId id, size_t size, Thread* t) {
-  assert(jfr_is_event_enabled(id), "invariant");
   if (t->jfr_thread_local()->has_native_buffer()) {
     JfrStorage::Buffer* const buffer = t->jfr_thread_local()->native_buffer();
     if (LessThanSize<JfrStorage::Buffer>::evaluate(buffer, size)) {
--- a/src/hotspot/share/oops/cpCache.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/oops/cpCache.cpp	Thu May 30 19:49:55 2019 +0200
@@ -261,11 +261,22 @@
         method->name() != vmSymbols::object_initializer_name()) {
       do_resolve = false;
     }
-    // Don't mark invokestatic to method as resolved if the holder class has not yet completed
-    // initialization. An invokestatic must only proceed if the class is initialized, but if
-    // we resolve it before then that class initialization check is skipped.
-    if (invoke_code == Bytecodes::_invokestatic && !method->method_holder()->is_initialized()) {
-      do_resolve = false;
+    if (invoke_code == Bytecodes::_invokestatic) {
+      assert(method->method_holder()->is_initialized() ||
+             method->method_holder()->is_reentrant_initialization(Thread::current()),
+             "invalid class initialization state for invoke_static");
+
+      if (!VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
+        // Don't mark invokestatic to method as resolved if the holder class has not yet completed
+        // initialization. An invokestatic must only proceed if the class is initialized, but if
+        // we resolve it before then that class initialization check is skipped.
+        //
+        // When fast class initialization checks are supported (VM_Version::supports_fast_class_init_checks() == true),
+        // template interpreter supports fast class initialization check for
+        // invokestatic which doesn't require call site re-resolution to
+        // enforce class initialization barrier.
+        do_resolve = false;
+      }
     }
     if (do_resolve) {
       set_bytecode_1(invoke_code);
--- a/src/hotspot/share/oops/method.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/oops/method.cpp	Thu May 30 19:49:55 2019 +0200
@@ -704,6 +704,10 @@
    return name() == vmSymbols::object_initializer_name();
 }
 
+bool Method::needs_clinit_barrier() const {
+  return is_static() && !method_holder()->is_initialized();
+}
+
 objArrayHandle Method::resolved_checked_exceptions_impl(Method* method, TRAPS) {
   int length = method->checked_exceptions_length();
   if (length == 0) {  // common case
--- a/src/hotspot/share/oops/method.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/oops/method.hpp	Thu May 30 19:49:55 2019 +0200
@@ -699,6 +699,8 @@
   bool has_aot_code() const                      { return aot_code() != NULL; }
 #endif
 
+  bool needs_clinit_barrier() const;
+
   // sizing
   static int header_size()                       {
     return align_up((int)sizeof(Method), wordSize) / wordSize;
--- a/src/hotspot/share/oops/methodData.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/oops/methodData.hpp	Thu May 30 19:49:55 2019 +0200
@@ -2012,7 +2012,7 @@
 
   // Whole-method sticky bits and flags
   enum {
-    _trap_hist_limit    = 24 JVMCI_ONLY(+5),   // decoupled from Deoptimization::Reason_LIMIT
+    _trap_hist_limit    = 25 JVMCI_ONLY(+5),   // decoupled from Deoptimization::Reason_LIMIT
     _trap_hist_mask     = max_jubyte,
     _extra_data_count   = 4     // extra DataLayout headers, for trap history
   }; // Public flag values
--- a/src/hotspot/share/opto/bytecodeInfo.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/bytecodeInfo.cpp	Thu May 30 19:49:55 2019 +0200
@@ -202,15 +202,15 @@
   const char* fail_msg = NULL;
 
   // First check all inlining restrictions which are required for correctness
-  if ( callee_method->is_abstract()) {
+  if (callee_method->is_abstract()) {
     fail_msg = "abstract method"; // // note: we allow ik->is_abstract()
   } else if (!callee_method->holder()->is_initialized() &&
              // access allowed in the context of static initializer
-             !C->is_compiling_clinit_for(callee_method->holder())) {
+             C->needs_clinit_barrier(callee_method->holder(), caller_method)) {
     fail_msg = "method holder not initialized";
-  } else if ( callee_method->is_native()) {
+  } else if (callee_method->is_native()) {
     fail_msg = "native method";
-  } else if ( callee_method->dont_inline()) {
+  } else if (callee_method->dont_inline()) {
     fail_msg = "don't inline by annotation";
   }
 
@@ -478,14 +478,18 @@
 
 //------------------------------pass_initial_checks----------------------------
 bool InlineTree::pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* callee_method) {
-  ciInstanceKlass *callee_holder = callee_method ? callee_method->holder() : NULL;
   // Check if a callee_method was suggested
-  if( callee_method == NULL )            return false;
+  if (callee_method == NULL) {
+    return false;
+  }
+  ciInstanceKlass *callee_holder = callee_method->holder();
   // Check if klass of callee_method is loaded
-  if( !callee_holder->is_loaded() )      return false;
-  if( !callee_holder->is_initialized() &&
+  if (!callee_holder->is_loaded()) {
+    return false;
+  }
+  if (!callee_holder->is_initialized() &&
       // access allowed in the context of static initializer
-      !C->is_compiling_clinit_for(callee_holder)) {
+      C->needs_clinit_barrier(callee_holder, caller_method)) {
     return false;
   }
   if( !UseInterpreter ) /* running Xcomp */ {
--- a/src/hotspot/share/opto/compile.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/compile.cpp	Thu May 30 19:49:55 2019 +0200
@@ -654,6 +654,7 @@
                   _trace_opto_output(directive->TraceOptoOutputOption),
 #endif
                   _has_method_handle_invokes(false),
+                  _clinit_barrier_on_entry(false),
                   _comp_arena(mtCompiler),
                   _barrier_set_state(BarrierSet::barrier_set()->barrier_set_c2()->create_barrier_state(comp_arena())),
                   _env(ci_env),
@@ -988,6 +989,7 @@
     _trace_opto_output(directive->TraceOptoOutputOption),
 #endif
     _has_method_handle_invokes(false),
+    _clinit_barrier_on_entry(false),
     _comp_arena(mtCompiler),
     _env(ci_env),
     _directive(directive),
@@ -1170,6 +1172,9 @@
     }
   }
 #endif
+  if (VM_Version::supports_fast_class_init_checks() && has_method() && !is_osr_compilation() && method()->needs_clinit_barrier()) {
+    set_clinit_barrier_on_entry(true);
+  }
   if (debug_info()->recording_non_safepoints()) {
     set_node_note_array(new(comp_arena()) GrowableArray<Node_Notes*>
                         (comp_arena(), 8, 0, NULL));
@@ -3841,9 +3846,42 @@
   }
 }
 
-bool Compile::is_compiling_clinit_for(ciKlass* k) {
-  ciMethod* root = method(); // the root method of compilation
-  return root->is_static_initializer() && root->holder() == k; // access in the context of clinit
+bool Compile::needs_clinit_barrier(ciMethod* method, ciMethod* accessing_method) {
+  return method->is_static() && needs_clinit_barrier(method->holder(), accessing_method);
+}
+
+bool Compile::needs_clinit_barrier(ciField* field, ciMethod* accessing_method) {
+  return field->is_static() && needs_clinit_barrier(field->holder(), accessing_method);
+}
+
+bool Compile::needs_clinit_barrier(ciInstanceKlass* holder, ciMethod* accessing_method) {
+  if (holder->is_initialized()) {
+    return false;
+  }
+  if (holder->is_being_initialized()) {
+    if (accessing_method->holder() == holder) {
+      // Access inside a class. The barrier can be elided when access happens in <clinit>,
+      // <init>, or a static method. In all those cases, there was an initialization
+      // barrier on the holder klass passed.
+      if (accessing_method->is_static_initializer() ||
+          accessing_method->is_object_initializer() ||
+          accessing_method->is_static()) {
+        return false;
+      }
+    } else if (accessing_method->holder()->is_subclass_of(holder)) {
+      // Access from a subclass. The barrier can be elided only when access happens in <clinit>.
+      // In case of <init> or a static method, the barrier is on the subclass is not enough:
+      // child class can become fully initialized while its parent class is still being initialized.
+      if (accessing_method->is_static_initializer()) {
+        return false;
+      }
+    }
+    ciMethod* root = method(); // the root method of compilation
+    if (root != accessing_method) {
+      return needs_clinit_barrier(holder, root); // check access in the context of compilation root
+    }
+  }
+  return true;
 }
 
 #ifndef PRODUCT
--- a/src/hotspot/share/opto/compile.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/compile.hpp	Thu May 30 19:49:55 2019 +0200
@@ -416,6 +416,7 @@
   bool                  _has_method_handle_invokes; // True if this method has MethodHandle invokes.
   RTMState              _rtm_state;             // State of Restricted Transactional Memory usage
   int                   _loop_opts_cnt;         // loop opts round
+  bool                  _clinit_barrier_on_entry; // True if clinit barrier is needed on nmethod entry
 
   // Compilation environment.
   Arena                 _comp_arena;            // Arena with lifetime equivalent to Compile
@@ -714,6 +715,8 @@
   bool          profile_rtm() const              { return _rtm_state == ProfileRTM; }
   uint              max_node_limit() const       { return (uint)_max_node_limit; }
   void          set_max_node_limit(uint n)       { _max_node_limit = n; }
+  bool              clinit_barrier_on_entry()       { return _clinit_barrier_on_entry; }
+  void          set_clinit_barrier_on_entry(bool z) { _clinit_barrier_on_entry = z; }
 
   // check the CompilerOracle for special behaviours for this compile
   bool          method_has_option(const char * option) {
@@ -1381,7 +1384,9 @@
   CloneMap&     clone_map();
   void          set_clone_map(Dict* d);
 
-  bool is_compiling_clinit_for(ciKlass* k);
+  bool needs_clinit_barrier(ciField* ik,         ciMethod* accessing_method);
+  bool needs_clinit_barrier(ciMethod* ik,        ciMethod* accessing_method);
+  bool needs_clinit_barrier(ciInstanceKlass* ik, ciMethod* accessing_method);
 };
 
 #endif // SHARE_OPTO_COMPILE_HPP
--- a/src/hotspot/share/opto/graphKit.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/graphKit.cpp	Thu May 30 19:49:55 2019 +0200
@@ -2854,6 +2854,60 @@
   return false;
 }
 
+void GraphKit::guard_klass_being_initialized(Node* klass) {
+  int init_state_off = in_bytes(InstanceKlass::init_state_offset());
+  Node* adr = basic_plus_adr(top(), klass, init_state_off);
+  Node* init_state = LoadNode::make(_gvn, NULL, immutable_memory(), adr,
+                                    adr->bottom_type()->is_ptr(), TypeInt::BYTE,
+                                    T_BYTE, MemNode::unordered);
+  init_state = _gvn.transform(init_state);
+
+  Node* being_initialized_state = makecon(TypeInt::make(InstanceKlass::being_initialized));
+
+  Node* chk = _gvn.transform(new CmpINode(being_initialized_state, init_state));
+  Node* tst = _gvn.transform(new BoolNode(chk, BoolTest::eq));
+
+  { BuildCutout unless(this, tst, PROB_MAX);
+    uncommon_trap(Deoptimization::Reason_initialized, Deoptimization::Action_reinterpret);
+  }
+}
+
+void GraphKit::guard_init_thread(Node* klass) {
+  int init_thread_off = in_bytes(InstanceKlass::init_thread_offset());
+  Node* adr = basic_plus_adr(top(), klass, init_thread_off);
+
+  Node* init_thread = LoadNode::make(_gvn, NULL, immutable_memory(), adr,
+                                     adr->bottom_type()->is_ptr(), TypePtr::NOTNULL,
+                                     T_ADDRESS, MemNode::unordered);
+  init_thread = _gvn.transform(init_thread);
+
+  Node* cur_thread = _gvn.transform(new ThreadLocalNode());
+
+  Node* chk = _gvn.transform(new CmpPNode(cur_thread, init_thread));
+  Node* tst = _gvn.transform(new BoolNode(chk, BoolTest::eq));
+
+  { BuildCutout unless(this, tst, PROB_MAX);
+    uncommon_trap(Deoptimization::Reason_uninitialized, Deoptimization::Action_none);
+  }
+}
+
+void GraphKit::clinit_barrier(ciInstanceKlass* ik, ciMethod* context) {
+  if (ik->is_being_initialized()) {
+    if (C->needs_clinit_barrier(ik, context)) {
+      Node* klass = makecon(TypeKlassPtr::make(ik));
+      guard_klass_being_initialized(klass);
+      guard_init_thread(klass);
+      insert_mem_bar(Op_MemBarCPUOrder);
+    }
+  } else if (ik->is_initialized()) {
+    return; // no barrier needed
+  } else {
+    uncommon_trap(Deoptimization::Reason_uninitialized,
+                  Deoptimization::Action_reinterpret,
+                  NULL);
+  }
+}
+
 //------------------------maybe_cast_profiled_receiver-------------------------
 // If the profile has seen exactly one type, narrow to exactly that type.
 // Subsequent type checks will always fold up.
--- a/src/hotspot/share/opto/graphKit.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/graphKit.hpp	Thu May 30 19:49:55 2019 +0200
@@ -386,6 +386,11 @@
   // Check the null_seen bit.
   bool seems_never_null(Node* obj, ciProfileData* data, bool& speculating);
 
+  void guard_klass_being_initialized(Node* klass);
+  void guard_init_thread(Node* klass);
+
+  void clinit_barrier(ciInstanceKlass* ik, ciMethod* context);
+
   // Check for unique class for receiver at call
   ciKlass* profile_has_unique_klass() {
     ciCallProfile profile = method()->call_profile_at_bci(bci());
--- a/src/hotspot/share/opto/machnode.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/machnode.hpp	Thu May 30 19:49:55 2019 +0200
@@ -301,7 +301,14 @@
 
   // Bottom_type call; value comes from operand0
   virtual const class Type *bottom_type() const { return _opnds[0]->type(); }
-  virtual uint ideal_reg() const { const Type *t = _opnds[0]->type(); return t == TypeInt::CC ? Op_RegFlags : t->ideal_reg(); }
+  virtual uint ideal_reg() const {
+    const Type *t = _opnds[0]->type();
+    if (t == TypeInt::CC) {
+      return Op_RegFlags;
+    } else {
+      return t->ideal_reg();
+    }
+  }
 
   // If this is a memory op, return the base pointer and fixed offset.
   // If there are no such, return NULL.  If there are multiple addresses
--- a/src/hotspot/share/opto/node.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/node.hpp	Thu May 30 19:49:55 2019 +0200
@@ -998,7 +998,7 @@
   // the node is guaranteed never to compare equal to any other node.
   // If we accidentally generate a hash with value NO_HASH the node
   // won't go into the table and we'll lose a little optimization.
-  enum { NO_HASH = 0 };
+  static const uint NO_HASH = 0;
   virtual uint hash() const;
   virtual bool cmp( const Node &n ) const;
 
--- a/src/hotspot/share/opto/parse.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/parse.hpp	Thu May 30 19:49:55 2019 +0200
@@ -482,6 +482,8 @@
   // Helper function to compute array addressing
   Node* array_addressing(BasicType type, int vals, const Type* *result2=NULL);
 
+  void clinit_deopt();
+
   void rtm_deopt();
 
   // Pass current map to exits
@@ -530,14 +532,12 @@
 
   // common code for making initial checks and forming addresses
   void do_field_access(bool is_get, bool is_field);
-  bool static_field_ok_in_clinit(ciField *field, ciMethod *method);
 
   // common code for actually performing the load or store
   void do_get_xxx(Node* obj, ciField* field, bool is_field);
   void do_put_xxx(Node* obj, ciField* field, bool is_field);
 
   // implementation of object creation bytecodes
-  void emit_guard_for_new(ciInstanceKlass* klass);
   void do_new();
   void do_newarray(BasicType elemtype);
   void do_anewarray();
--- a/src/hotspot/share/opto/parse1.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/parse1.cpp	Thu May 30 19:49:55 2019 +0200
@@ -584,6 +584,11 @@
   }
 
   if (depth() == 1 && !failing()) {
+    if (C->clinit_barrier_on_entry()) {
+      // Add check to deoptimize the nmethod once the holder class is fully initialized
+      clinit_deopt();
+    }
+
     // Add check to deoptimize the nmethod if RTM state was changed
     rtm_deopt();
   }
@@ -1192,7 +1197,7 @@
 // The main thing to do is lock the receiver of a synchronized method.
 void Parse::do_method_entry() {
   set_parse_bci(InvocationEntryBci); // Pseudo-BCP
-  set_sp(0);                      // Java Stack Pointer
+  set_sp(0);                         // Java Stack Pointer
 
   NOT_PRODUCT( count_compiled_calls(true/*at_method_entry*/, false/*is_inline*/); )
 
@@ -2102,11 +2107,25 @@
   set_control( _gvn.transform(result_rgn) );
 }
 
+// Add check to deoptimize once holder klass is fully initialized.
+void Parse::clinit_deopt() {
+  assert(C->has_method(), "only for normal compilations");
+  assert(depth() == 1, "only for main compiled method");
+  assert(is_normal_parse(), "no barrier needed on osr entry");
+  assert(method()->holder()->is_being_initialized() || method()->holder()->is_initialized(),
+         "initialization should have been started");
+
+  set_parse_bci(0);
+
+  Node* holder = makecon(TypeKlassPtr::make(method()->holder()));
+  guard_klass_being_initialized(holder);
+}
+
 // Add check to deoptimize if RTM state is not ProfileRTM
 void Parse::rtm_deopt() {
 #if INCLUDE_RTM_OPT
   if (C->profile_rtm()) {
-    assert(C->method() != NULL, "only for normal compilations");
+    assert(C->has_method(), "only for normal compilations");
     assert(!C->method()->method_data()->is_empty(), "MDO is needed to record RTM state");
     assert(depth() == 1, "generate check only for main compiled method");
 
--- a/src/hotspot/share/opto/parse3.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/parse3.cpp	Thu May 30 19:49:55 2019 +0200
@@ -40,39 +40,6 @@
 //=============================================================================
 // Helper methods for _get* and _put* bytecodes
 //=============================================================================
-bool Parse::static_field_ok_in_clinit(ciField *field, ciMethod *method) {
-  // Could be the field_holder's <clinit> method, or <clinit> for a subklass.
-  // Better to check now than to Deoptimize as soon as we execute
-  assert( field->is_static(), "Only check if field is static");
-  // is_being_initialized() is too generous.  It allows access to statics
-  // by threads that are not running the <clinit> before the <clinit> finishes.
-  // return field->holder()->is_being_initialized();
-
-  // The following restriction is correct but conservative.
-  // It is also desirable to allow compilation of methods called from <clinit>
-  // but this generated code will need to be made safe for execution by
-  // other threads, or the transition from interpreted to compiled code would
-  // need to be guarded.
-  ciInstanceKlass *field_holder = field->holder();
-
-  if (method->holder()->is_subclass_of(field_holder)) {
-    if (method->is_static_initializer()) {
-      // OK to access static fields inside initializer
-      return true;
-    } else if (method->is_object_initializer()) {
-      // It's also OK to access static fields inside a constructor,
-      // because any thread calling the constructor must first have
-      // synchronized on the class by executing a '_new' bytecode.
-      return true;
-    }
-  }
-  if (C->is_compiling_clinit_for(field_holder)) {
-    return true; // access in the context of static initializer
-  }
-  return false;
-}
-
-
 void Parse::do_field_access(bool is_get, bool is_field) {
   bool will_link;
   ciField* field = iter().get_field(will_link);
@@ -88,15 +55,6 @@
     return;
   }
 
-  if (!is_field && !field_holder->is_initialized()) {
-    if (!static_field_ok_in_clinit(field, method())) {
-      uncommon_trap(Deoptimization::Reason_uninitialized,
-                    Deoptimization::Action_reinterpret,
-                    NULL, "!static_field_ok_in_clinit");
-      return;
-    }
-  }
-
   // Deoptimize on putfield writes to call site target field.
   if (!is_get && field->is_call_site_target()) {
     uncommon_trap(Deoptimization::Reason_unhandled,
@@ -105,6 +63,11 @@
     return;
   }
 
+  if (C->needs_clinit_barrier(field, method())) {
+    clinit_barrier(field_holder, method());
+    if (stopped())  return;
+  }
+
   assert(field->will_link(method(), bc()), "getfield: typeflow responsibility");
 
   // Note:  We do not check for an unloaded field type here any more.
--- a/src/hotspot/share/opto/parseHelper.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/opto/parseHelper.cpp	Thu May 30 19:49:55 2019 +0200
@@ -235,45 +235,6 @@
 }
 
 
-void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
-  // Emit guarded new
-  //   if (klass->_init_thread != current_thread ||
-  //       klass->_init_state != being_initialized)
-  //      uncommon_trap
-  Node* cur_thread = _gvn.transform( new ThreadLocalNode() );
-  Node* merge = new RegionNode(3);
-  _gvn.set_type(merge, Type::CONTROL);
-  Node* kls = makecon(TypeKlassPtr::make(klass));
-
-  Node* init_thread_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_thread_offset()));
-  Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset);
-  Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered);
-  Node *tst   = Bool( CmpP( init_thread, cur_thread), BoolTest::eq);
-  IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
-  set_control(IfTrue(iff));
-  merge->set_req(1, IfFalse(iff));
-
-  Node* init_state_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_state_offset()));
-  adr_node = basic_plus_adr(kls, kls, init_state_offset);
-  // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
-  // can generate code to load it as unsigned byte.
-  Node* init_state = make_load(NULL, adr_node, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered);
-  Node* being_init = _gvn.intcon(InstanceKlass::being_initialized);
-  tst   = Bool( CmpI( init_state, being_init), BoolTest::eq);
-  iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
-  set_control(IfTrue(iff));
-  merge->set_req(2, IfFalse(iff));
-
-  PreserveJVMState pjvms(this);
-  record_for_igvn(merge);
-  set_control(merge);
-
-  uncommon_trap(Deoptimization::Reason_uninitialized,
-                Deoptimization::Action_reinterpret,
-                klass);
-}
-
-
 //------------------------------do_new-----------------------------------------
 void Parse::do_new() {
   kill_dead_locals();
@@ -282,18 +243,19 @@
   ciInstanceKlass* klass = iter().get_klass(will_link)->as_instance_klass();
   assert(will_link, "_new: typeflow responsibility");
 
-  // Should initialize, or throw an InstantiationError?
-  if ((!klass->is_initialized() && !klass->is_being_initialized()) ||
-      klass->is_abstract() || klass->is_interface() ||
+  // Should throw an InstantiationError?
+  if (klass->is_abstract() || klass->is_interface() ||
       klass->name() == ciSymbol::java_lang_Class() ||
       iter().is_unresolved_klass()) {
-    uncommon_trap(Deoptimization::Reason_uninitialized,
-                  Deoptimization::Action_reinterpret,
+    uncommon_trap(Deoptimization::Reason_unhandled,
+                  Deoptimization::Action_none,
                   klass);
     return;
   }
-  if (klass->is_being_initialized()) {
-    emit_guard_for_new(klass);
+
+  if (C->needs_clinit_barrier(klass, method())) {
+    clinit_barrier(klass, method());
+    if (stopped())  return;
   }
 
   Node* kls = makecon(TypeKlassPtr::make(klass));
--- a/src/hotspot/share/prims/jvmti.xml	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/prims/jvmti.xml	Thu May 30 19:49:55 2019 +0200
@@ -7437,7 +7437,7 @@
       <capabilities>
         <capability id="can_redefine_any_class">
           If possessed then all classes (except primitive, array, and some implementation defined
-          classes) are modifiable (redefine or retransform).
+          classes) are modifiable with <functionlink id="RedefineClasses"/>.
         </capability>
         <capability id="can_retransform_any_class">
           If possessed then all classes (except primitive, array, and some implementation defined
@@ -10199,8 +10199,10 @@
       </capabilityfield>
       <capabilityfield id="can_redefine_any_class">
 	<description>
-          Can modify (retransform or redefine) any modifiable class.
+          <functionlink id="RedefineClasses"/> can be called on any modifiable class.
           See <functionlink id="IsModifiableClass"/>.
+          (<fieldlink id="can_redefine_classes" struct="jvmtiCapabilities"/>
+          must also be set)
 	</description>
       </capabilityfield>
       <capabilityfield id="can_get_current_thread_cpu_time">
@@ -14957,6 +14959,12 @@
         - Add new error JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED
           that can be returned by RedefineClasses and RetransformClasses.
   </change>
+  <change date="20 May 2019" version="13.0.0">
+      Minor spec update for the capability "can_redefine_any_class".
+      It now says:
+       "RedefineClasses can be called on any modifiable class. See IsModifiableClass.
+       (can_redefine_classes must also be set)"
+  </change>
 </changehistory>
 
 </specification>
--- a/src/hotspot/share/runtime/arguments.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/runtime/arguments.cpp	Thu May 30 19:49:55 2019 +0200
@@ -1722,9 +1722,33 @@
 static const size_t DefaultHeapBaseMinAddress = HeapBaseMinAddress;
 
 void Arguments::set_heap_size() {
-  julong phys_mem =
-    FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
-                            : (julong)MaxRAM;
+  julong phys_mem;
+
+  // If the user specified one of these options, they
+  // want specific memory sizing so do not limit memory
+  // based on compressed oops addressability.
+  // Also, memory limits will be calculated based on
+  // available os physical memory, not our MaxRAM limit,
+  // unless MaxRAM is also specified.
+  bool override_coop_limit = (!FLAG_IS_DEFAULT(MaxRAMPercentage) ||
+                           !FLAG_IS_DEFAULT(MaxRAMFraction) ||
+                           !FLAG_IS_DEFAULT(MinRAMPercentage) ||
+                           !FLAG_IS_DEFAULT(MinRAMFraction) ||
+                           !FLAG_IS_DEFAULT(InitialRAMPercentage) ||
+                           !FLAG_IS_DEFAULT(InitialRAMFraction) ||
+                           !FLAG_IS_DEFAULT(MaxRAM));
+  if (override_coop_limit) {
+    if (FLAG_IS_DEFAULT(MaxRAM)) {
+      phys_mem = os::physical_memory();
+      FLAG_SET_ERGO(MaxRAM, (uint64_t)phys_mem);
+    } else {
+      phys_mem = (julong)MaxRAM;
+    }
+  } else {
+    phys_mem = FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
+                                       : (julong)MaxRAM;
+  }
+
 
   // Convert deprecated flags
   if (FLAG_IS_DEFAULT(MaxRAMPercentage) &&
@@ -1780,7 +1804,19 @@
         // but it should be not less than default MaxHeapSize.
         max_coop_heap -= HeapBaseMinAddress;
       }
-      reasonable_max = MIN2(reasonable_max, max_coop_heap);
+
+      // If user specified flags prioritizing os physical
+      // memory limits, then disable compressed oops if
+      // limits exceed max_coop_heap and UseCompressedOops
+      // was not specified.
+      if (reasonable_max > max_coop_heap) {
+        if (FLAG_IS_ERGO(UseCompressedOops) && override_coop_limit) {
+          FLAG_SET_ERGO(UseCompressedOops, false);
+          FLAG_SET_ERGO(UseCompressedClassPointers, false);
+        } else {
+          reasonable_max = MIN2(reasonable_max, max_coop_heap);
+        }
+      }
     }
     reasonable_max = limit_by_allocatable_memory(reasonable_max);
 
--- a/src/hotspot/share/runtime/deoptimization.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Thu May 30 19:49:55 2019 +0200
@@ -2176,6 +2176,7 @@
   "profile_predicate",
   "unloaded",
   "uninitialized",
+  "initialized",
   "unreached",
   "unhandled",
   "constraint",
--- a/src/hotspot/share/runtime/deoptimization.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/runtime/deoptimization.hpp	Thu May 30 19:49:55 2019 +0200
@@ -72,6 +72,7 @@
     // recorded per method
     Reason_unloaded,              // unloaded class or constant pool entry
     Reason_uninitialized,         // bad class state (uninitialized)
+    Reason_initialized,           // class has been fully initialized
     Reason_unreached,             // code is not reached, compiler
     Reason_unhandled,             // arbitrary compiler limitation
     Reason_constraint,            // arbitrary runtime constraint violated
--- a/src/hotspot/share/runtime/globals.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/runtime/globals.hpp	Thu May 30 19:49:55 2019 +0200
@@ -444,7 +444,7 @@
   diagnostic(bool, LogEvents, true,                                         \
           "Enable the various ring buffer event logs")                      \
                                                                             \
-  diagnostic(uintx, LogEventsBufferEntries, 10,                             \
+  diagnostic(uintx, LogEventsBufferEntries, 20,                             \
           "Number of ring buffer event logs")                               \
           range(1, NOT_LP64(1*K) LP64_ONLY(1*M))                            \
                                                                             \
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Thu May 30 19:49:55 2019 +0200
@@ -1314,6 +1314,12 @@
           }
         }
       } else {
+        if (VM_Version::supports_fast_class_init_checks() &&
+            invoke_code == Bytecodes::_invokestatic &&
+            callee_method->needs_clinit_barrier() &&
+            callee != NULL && (callee->is_compiled_by_jvmci() || callee->is_aot())) {
+          return true; // skip patching for JVMCI or AOT code
+        }
         CompiledStaticCall* ssc = caller_nm->compiledStaticCall_before(caller_frame.pc());
         if (ssc->is_clean()) ssc->set(static_call_info);
       }
@@ -1376,12 +1382,20 @@
   }
 #endif
 
-  // Do not patch call site for static call when the class is not
-  // fully initialized.
-  if (invoke_code == Bytecodes::_invokestatic &&
-      !callee_method->method_holder()->is_initialized()) {
-    assert(callee_method->method_holder()->is_linked(), "must be");
-    return callee_method;
+  if (invoke_code == Bytecodes::_invokestatic) {
+    assert(callee_method->method_holder()->is_initialized() ||
+           callee_method->method_holder()->is_reentrant_initialization(thread),
+           "invalid class initialization state for invoke_static");
+    if (!VM_Version::supports_fast_class_init_checks() && callee_method->needs_clinit_barrier()) {
+      // In order to keep class initialization check, do not patch call
+      // site for static call when the class is not fully initialized.
+      // Proper check is enforced by call site re-resolution on every invocation.
+      //
+      // When fast class initialization checks are supported (VM_Version::supports_fast_class_init_checks() == true),
+      // explicit class initialization check is put in nmethod entry (VEP).
+      assert(callee_method->method_holder()->is_linked(), "must be");
+      return callee_method;
+    }
   }
 
   // JSR 292 key invariant:
--- a/src/hotspot/share/runtime/vmStructs.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Thu May 30 19:49:55 2019 +0200
@@ -2388,6 +2388,7 @@
   declare_constant(Deoptimization::Reason_profile_predicate)              \
   declare_constant(Deoptimization::Reason_unloaded)                       \
   declare_constant(Deoptimization::Reason_uninitialized)                  \
+  declare_constant(Deoptimization::Reason_initialized)                    \
   declare_constant(Deoptimization::Reason_unreached)                      \
   declare_constant(Deoptimization::Reason_unhandled)                      \
   declare_constant(Deoptimization::Reason_constraint)                     \
--- a/src/hotspot/share/runtime/vm_version.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/runtime/vm_version.hpp	Thu May 30 19:49:55 2019 +0200
@@ -171,6 +171,9 @@
   // Does this CPU support spin wait instruction?
   static bool supports_on_spin_wait() { return false; }
 
+  // Does platform support fast class initialization checks for static methods?
+  static bool supports_fast_class_init_checks() { return false; }
+
   static bool print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]);
 };
 
--- a/src/hotspot/share/utilities/bitMap.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/utilities/bitMap.cpp	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/hotspot/share/utilities/bitMap.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/utilities/bitMap.hpp	Thu May 30 19:49:55 2019 +0200
@@ -383,16 +383,16 @@
   // Resize the backing bitmap memory.
   //
   // Old bits are transfered to the new memory
-  // and the extended memory is cleared.
+  // and the extended memory is (optionally) cleared.
   void resize(idx_t new_size_in_bits, bool clear = true);
 
-  // Set up and clear the bitmap memory.
+  // Set up and (optionally) clear the bitmap memory.
   //
   // Precondition: The bitmap was default constructed and has
   // not yet had memory allocated via resize or initialize.
   void initialize(idx_t size_in_bits, bool clear = true);
 
-  // Set up and clear the bitmap memory.
+  // Set up and (optionally) clear the bitmap memory.
   //
   // Can be called on previously initialized bitmaps.
   void reinitialize(idx_t size_in_bits, bool clear = true);
--- a/src/hotspot/share/utilities/events.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/utilities/events.cpp	Thu May 30 19:49:55 2019 +0200
@@ -127,7 +127,7 @@
   st.print("Exception <");
   h_exception->print_value_on(&st);
   st.print("%s%s> (" INTPTR_FORMAT ") \n"
-           "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
+           "thrown [%s, line %d]",
            message ? ": " : "", message ? message : "",
-           p2i(h_exception()), file, line, p2i(thread));
+           p2i(h_exception()), file, line);
 }
--- a/src/hotspot/share/utilities/events.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/utilities/events.hpp	Thu May 30 19:49:55 2019 +0200
@@ -232,7 +232,7 @@
 };
 
 inline void Events::log(Thread* thread, const char* format, ...) {
-  if (LogEvents) {
+  if (LogEvents && _messages != NULL) {
     va_list ap;
     va_start(ap, format);
     _messages->logv(thread, format, ap);
@@ -241,7 +241,7 @@
 }
 
 inline void Events::log_exception(Thread* thread, const char* format, ...) {
-  if (LogEvents) {
+  if (LogEvents && _exceptions != NULL) {
     va_list ap;
     va_start(ap, format);
     _exceptions->logv(thread, format, ap);
@@ -250,13 +250,13 @@
 }
 
 inline void Events::log_exception(Thread* thread, Handle h_exception, const char* message, const char* file, int line) {
-  if (LogEvents) {
+  if (LogEvents && _exceptions != NULL) {
     _exceptions->log(thread, h_exception, message, file, line);
   }
 }
 
 inline void Events::log_redefinition(Thread* thread, const char* format, ...) {
-  if (LogEvents) {
+  if (LogEvents && _redefinitions != NULL) {
     va_list ap;
     va_start(ap, format);
     _redefinitions->logv(thread, format, ap);
@@ -265,13 +265,13 @@
 }
 
 inline void Events::log_class_unloading(Thread* thread, InstanceKlass* ik) {
-  if (LogEvents) {
+  if (LogEvents && _class_unloading != NULL) {
     _class_unloading->log(thread, ik);
   }
 }
 
 inline void Events::log_deopt_message(Thread* thread, const char* format, ...) {
-  if (LogEvents) {
+  if (LogEvents && _deopt_messages != NULL) {
     va_list ap;
     va_start(ap, format);
     _deopt_messages->logv(thread, format, ap);
--- a/src/hotspot/share/utilities/globalDefinitions.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp	Thu May 30 19:49:55 2019 +0200
@@ -97,6 +97,9 @@
 #ifndef JLONG_FORMAT
 #define JLONG_FORMAT           INT64_FORMAT
 #endif
+#ifndef JLONG_FORMAT_W
+#define JLONG_FORMAT_W(width)  INT64_FORMAT_W(width)
+#endif
 #ifndef JULONG_FORMAT
 #define JULONG_FORMAT          UINT64_FORMAT
 #endif
--- a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp	Thu May 30 19:49:55 2019 +0200
@@ -250,7 +250,8 @@
 #define offsetof(klass,field) offset_of(klass,field)
 
 #if defined(_LP64) && defined(__APPLE__)
-#define JLONG_FORMAT           "%ld"
+#define JLONG_FORMAT          "%ld"
+#define JLONG_FORMAT_W(width) "%" #width "ld"
 #endif // _LP64 && __APPLE__
 
 #ifndef USE_LIBRARY_BASED_TLS_ONLY
--- a/src/hotspot/share/utilities/ostream.cpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/utilities/ostream.cpp	Thu May 30 19:49:55 2019 +0200
@@ -939,6 +939,7 @@
   buffer_pos    = 0;
   buffer_fixed  = false;
   buffer_max    = bufmax;
+  truncated     = false;
 }
 
 bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() {
@@ -947,12 +948,17 @@
   buffer_pos    = 0;
   buffer_fixed  = true;
   buffer_max    = bufmax;
+  truncated     = false;
 }
 
 void bufferedStream::write(const char* s, size_t len) {
 
+  if (truncated) {
+    return;
+  }
+
   if(buffer_pos + len > buffer_max) {
-    flush();
+    flush(); // Note: may be a noop.
   }
 
   size_t end = buffer_pos + len;
@@ -960,19 +966,42 @@
     if (buffer_fixed) {
       // if buffer cannot resize, silently truncate
       len = buffer_length - buffer_pos - 1;
+      truncated = true;
     } else {
       // For small overruns, double the buffer.  For larger ones,
       // increase to the requested size.
       if (end < buffer_length * 2) {
         end = buffer_length * 2;
       }
-      buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal);
-      buffer_length = end;
+      // Impose a cap beyond which the buffer cannot grow - a size which
+      // in all probability indicates a real error, e.g. faulty printing
+      // code looping, while not affecting cases of just-very-large-but-its-normal
+      // output.
+      const size_t reasonable_cap = MAX2(100 * M, buffer_max * 2);
+      if (end > reasonable_cap) {
+        // In debug VM, assert right away.
+        assert(false, "Exceeded max buffer size for this string.");
+        // Release VM: silently truncate. We do this since these kind of errors
+        // are both difficult to predict with testing (depending on logging content)
+        // and usually not serious enough to kill a production VM for it.
+        end = reasonable_cap;
+        size_t remaining = end - buffer_pos;
+        if (len >= remaining) {
+          len = remaining - 1;
+          truncated = true;
+        }
+      }
+      if (buffer_length < end) {
+        buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal);
+        buffer_length = end;
+      }
     }
   }
-  memcpy(buffer + buffer_pos, s, len);
-  buffer_pos += len;
-  update_position(s, len);
+  if (len > 0) {
+    memcpy(buffer + buffer_pos, s, len);
+    buffer_pos += len;
+    update_position(s, len);
+  }
 }
 
 char* bufferedStream::as_string() {
--- a/src/hotspot/share/utilities/ostream.hpp	Thu May 23 22:12:31 2019 +0200
+++ b/src/hotspot/share/utilities/ostream.hpp	Thu May 30 19:49:55 2019 +0200
@@ -267,6 +267,7 @@
   size_t buffer_max;
   size_t buffer_length;
   bool   buffer_fixed;
+  bool   truncated;
  public:
   bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10);
   bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax = 1024*1024*10);
--- a/src/java.base/macosx/classes/apple/security/KeychainStore.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/macosx/classes/apple/security/KeychainStore.java	Thu May 30 19:49:55 2019 +0200
@@ -1050,7 +1050,7 @@
         if (random == null) {
             random = new SecureRandom();
         }
-        salt = random.generateSeed(SALT_LEN);
+        random.nextBytes(salt);
         return salt;
     }
 
--- a/src/java.base/macosx/classes/java/net/DefaultInterface.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/macosx/classes/java/net/DefaultInterface.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * 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,8 @@
  * that returns null.
  */
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Enumeration;
 import java.io.IOException;
 
@@ -82,7 +84,8 @@
                     continue;
 
                 boolean ip4 = false, ip6 = false;
-                Enumeration<InetAddress> addrs = ni.getInetAddresses();
+                PrivilegedAction<Enumeration<InetAddress>> pa = ni::getInetAddresses;
+                Enumeration<InetAddress> addrs = AccessController.doPrivileged(pa);
                 while (addrs.hasMoreElements()) {
                     InetAddress addr = addrs.nextElement();
                     if (!addr.isAnyLocalAddress()) {
--- a/src/java.base/share/classes/java/io/FilePermission.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/io/FilePermission.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -440,8 +440,8 @@
      * <p>A pathname containing an empty string represents an empty path.
      *
      * @implNote In this implementation, the
-     * {@code jdk.io.permissionsUseCanonicalPath} system property dictates how
-     * the {@code path} argument is processed and stored.
+     * {@systemProperty jdk.io.permissionsUseCanonicalPath} system property
+     * dictates how the {@code path} argument is processed and stored.
      * <P>
      * If the value of the system property is set to {@code true}, {@code path}
      * is canonicalized and stored as a String object named {@code cpath}.
--- a/src/java.base/share/classes/java/io/ObjectInputFilter.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/io/ObjectInputFilter.java	Thu May 30 19:49:55 2019 +0200
@@ -205,7 +205,7 @@
      * <p>
      * The filter is configured during the initialization of the {@code ObjectInputFilter.Config}
      * class. For example, by calling {@link #getSerialFilter() Config.getSerialFilter}.
-     * If the system property {@code jdk.serialFilter} is defined, it is used
+     * If the system property {@systemProperty jdk.serialFilter} is defined, it is used
      * to configure the filter.
      * If the system property is not defined, and the {@link java.security.Security}
      * property {@code jdk.serialFilter} is defined then it is used to configure the filter.
--- a/src/java.base/share/classes/java/lang/String.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/lang/String.java	Thu May 30 19:49:55 2019 +0200
@@ -2690,21 +2690,21 @@
 
     /**
      * Returns a string whose value is this string, with all leading
-     * and trailing {@link Character#isWhitespace(int) white space}
+     * and trailing {@linkplain Character#isWhitespace(int) white space}
      * removed.
      * <p>
      * If this {@code String} object represents an empty string,
      * or if all code points in this string are
-     * {@link Character#isWhitespace(int) white space}, then an empty string
+     * {@linkplain Character#isWhitespace(int) white space}, then an empty string
      * is returned.
      * <p>
      * Otherwise, returns a substring of this string beginning with the first
-     * code point that is not a {@link Character#isWhitespace(int) white space}
+     * code point that is not a {@linkplain Character#isWhitespace(int) white space}
      * up to and including the last code point that is not a
-     * {@link Character#isWhitespace(int) white space}.
+     * {@linkplain Character#isWhitespace(int) white space}.
      * <p>
      * This method may be used to strip
-     * {@link Character#isWhitespace(int) white space} from
+     * {@linkplain Character#isWhitespace(int) white space} from
      * the beginning and end of a string.
      *
      * @return  a string whose value is this string, with all leading
@@ -2722,19 +2722,19 @@
 
     /**
      * Returns a string whose value is this string, with all leading
-     * {@link Character#isWhitespace(int) white space} removed.
+     * {@linkplain Character#isWhitespace(int) white space} removed.
      * <p>
      * If this {@code String} object represents an empty string,
      * or if all code points in this string are
-     * {@link Character#isWhitespace(int) white space}, then an empty string
+     * {@linkplain Character#isWhitespace(int) white space}, then an empty string
      * is returned.
      * <p>
      * Otherwise, returns a substring of this string beginning with the first
-     * code point that is not a {@link Character#isWhitespace(int) white space}
+     * code point that is not a {@linkplain Character#isWhitespace(int) white space}
      * up to and including the last code point of this string.
      * <p>
      * This method may be used to trim
-     * {@link Character#isWhitespace(int) white space} from
+     * {@linkplain Character#isWhitespace(int) white space} from
      * the beginning of a string.
      *
      * @return  a string whose value is this string, with all leading white
@@ -2752,19 +2752,19 @@
 
     /**
      * Returns a string whose value is this string, with all trailing
-     * {@link Character#isWhitespace(int) white space} removed.
+     * {@linkplain Character#isWhitespace(int) white space} removed.
      * <p>
      * If this {@code String} object represents an empty string,
      * or if all characters in this string are
-     * {@link Character#isWhitespace(int) white space}, then an empty string
+     * {@linkplain Character#isWhitespace(int) white space}, then an empty string
      * is returned.
      * <p>
      * Otherwise, returns a substring of this string beginning with the first
      * code point of this string up to and including the last code point
-     * that is not a {@link Character#isWhitespace(int) white space}.
+     * that is not a {@linkplain Character#isWhitespace(int) white space}.
      * <p>
      * This method may be used to trim
-     * {@link Character#isWhitespace(int) white space} from
+     * {@linkplain Character#isWhitespace(int) white space} from
      * the end of a string.
      *
      * @return  a string whose value is this string, with all trailing white
@@ -2782,11 +2782,11 @@
 
     /**
      * Returns {@code true} if the string is empty or contains only
-     * {@link Character#isWhitespace(int) white space} codepoints,
+     * {@linkplain Character#isWhitespace(int) white space} codepoints,
      * otherwise {@code false}.
      *
      * @return {@code true} if the string is empty or contains only
-     *         {@link Character#isWhitespace(int) white space} codepoints,
+     *         {@linkplain Character#isWhitespace(int) white space} codepoints,
      *         otherwise {@code false}
      *
      * @see Character#isWhitespace(int)
@@ -2849,10 +2849,10 @@
      * beginning of each line.
      * <p>
      * If {@code n < 0} then up to {@code n}
-     * {@link Character#isWhitespace(int) white space characters} are removed
+     * {@linkplain Character#isWhitespace(int) white space characters} are removed
      * from the beginning of each line. If a given line does not contain
      * sufficient white space then all leading
-     * {@link Character#isWhitespace(int) white space characters} are removed.
+     * {@linkplain Character#isWhitespace(int) white space characters} are removed.
      * Each white space character is treated as a single character. In
      * particular, the tab character {@code "\t"} (U+0009) is considered a
      * single character; it is not expanded.
@@ -2861,7 +2861,7 @@
      * terminators are still normalized.
      *
      * @param n  number of leading
-     *           {@link Character#isWhitespace(int) white space characters}
+     *           {@linkplain Character#isWhitespace(int) white space characters}
      *           to add or remove
      *
      * @return string with indentation adjusted and line endings normalized
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu May 30 19:49:55 2019 +0200
@@ -4980,8 +4980,10 @@
 
         // Step 1C: determine loop return type.
         // Step 1D: check other types.
-        final Class<?> loopReturnType = fini.stream().filter(Objects::nonNull).map(MethodHandle::type).
-                map(MethodType::returnType).findFirst().orElse(void.class);
+        // local variable required here; see JDK-8223553
+        Stream<Class<?>> cstream = fini.stream().filter(Objects::nonNull).map(MethodHandle::type)
+                .map(MethodType::returnType);
+        final Class<?> loopReturnType = cstream.findFirst().orElse(void.class);
         loopChecks1cd(pred, fini, loopReturnType);
 
         // Step 2: determine parameter lists.
--- a/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,9 +28,11 @@
 import java.io.IOException;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Objects;
 import java.util.Set;
 
 import sun.net.ResourceManager;
+import sun.net.ext.ExtendedSocketOptions;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -88,26 +90,6 @@
     }
 
     /**
-     * Returns a set of SocketOptions supported by this impl and by this impl's
-     * socket (Socket or ServerSocket)
-     *
-     * @return a Set of SocketOptions
-     */
-    @Override
-    protected Set<SocketOption<?>> supportedOptions() {
-        Set<SocketOption<?>> options;
-        if (isReusePortAvailable()) {
-            options = new HashSet<>();
-            options.addAll(super.supportedOptions());
-            options.add(StandardSocketOptions.SO_REUSEPORT);
-            options = Collections.unmodifiableSet(options);
-        } else {
-            options = super.supportedOptions();
-        }
-        return options;
-    }
-
-    /**
      * Creates a datagram socket
      */
     protected synchronized void create() throws SocketException {
@@ -400,6 +382,125 @@
         return result;
     }
 
+    static final ExtendedSocketOptions extendedOptions =
+            ExtendedSocketOptions.getInstance();
+
+    private static final Set<SocketOption<?>> datagramSocketOptions = datagramSocketOptions();
+    private static final Set<SocketOption<?>> multicastSocketOptions = multicastSocketOptions();
+
+    private static Set<SocketOption<?>> datagramSocketOptions() {
+        HashSet<SocketOption<?>> options = new HashSet<>();
+        options.add(StandardSocketOptions.SO_SNDBUF);
+        options.add(StandardSocketOptions.SO_RCVBUF);
+        options.add(StandardSocketOptions.SO_REUSEADDR);
+        options.add(StandardSocketOptions.IP_TOS);
+        if (isReusePortAvailable())
+            options.add(StandardSocketOptions.SO_REUSEPORT);
+        options.addAll(ExtendedSocketOptions.datagramSocketOptions());
+        return Collections.unmodifiableSet(options);
+    }
+
+    private static Set<SocketOption<?>> multicastSocketOptions() {
+        HashSet<SocketOption<?>> options = new HashSet<>();
+        options.add(StandardSocketOptions.SO_SNDBUF);
+        options.add(StandardSocketOptions.SO_RCVBUF);
+        options.add(StandardSocketOptions.SO_REUSEADDR);
+        options.add(StandardSocketOptions.IP_TOS);
+        options.add(StandardSocketOptions.IP_MULTICAST_IF);
+        options.add(StandardSocketOptions.IP_MULTICAST_TTL);
+        options.add(StandardSocketOptions.IP_MULTICAST_LOOP);
+        if (isReusePortAvailable())
+            options.add(StandardSocketOptions.SO_REUSEPORT);
+        options.addAll(ExtendedSocketOptions.datagramSocketOptions());
+        return Collections.unmodifiableSet(options);
+    }
+
+    @Override
+    protected Set<SocketOption<?>> supportedOptions() {
+        if (getDatagramSocket() instanceof MulticastSocket)
+            return multicastSocketOptions;
+        else
+            return datagramSocketOptions;
+    }
+
+    @Override
+    protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
+        Objects.requireNonNull(name);
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
+
+        if (!name.type().isInstance(value))
+            throw new IllegalArgumentException("Invalid value '" + value + "'");
+
+        if (isClosed())
+            throw new SocketException("Socket closed");
+
+        if (name == StandardSocketOptions.SO_SNDBUF) {
+            if (((Integer)value).intValue() < 0)
+                throw new IllegalArgumentException("Invalid send buffer size:" + value);
+            setOption(SocketOptions.SO_SNDBUF, value);
+        } else if (name == StandardSocketOptions.SO_RCVBUF) {
+            if (((Integer)value).intValue() < 0)
+                throw new IllegalArgumentException("Invalid recv buffer size:" + value);
+            setOption(SocketOptions.SO_RCVBUF, value);
+        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
+            setOption(SocketOptions.SO_REUSEADDR, value);
+        } else if (name == StandardSocketOptions.SO_REUSEPORT) {
+            setOption(SocketOptions.SO_REUSEPORT, value);
+        } else if (name == StandardSocketOptions.IP_TOS) {
+            int i = ((Integer)value).intValue();
+            if (i < 0 || i > 255)
+                throw new IllegalArgumentException("Invalid IP_TOS value: " + value);
+            setOption(SocketOptions.IP_TOS, value);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_IF ) {
+            setOption(SocketOptions.IP_MULTICAST_IF2, value);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_TTL) {
+            int i = ((Integer)value).intValue();
+            if (i < 0 || i > 255)
+                throw new IllegalArgumentException("Invalid TTL/hop value: " + value);
+            setTimeToLive((Integer)value);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_LOOP) {
+            setOption(SocketOptions.IP_MULTICAST_LOOP, value);
+        } else if (extendedOptions.isOptionSupported(name)) {
+            extendedOptions.setOption(fd, name, value);
+        } else {
+            throw new AssertionError("unknown option :" + name);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected <T> T getOption(SocketOption<T> name) throws IOException {
+        Objects.requireNonNull(name);
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
+
+        if (isClosed())
+            throw new SocketException("Socket closed");
+
+        if (name == StandardSocketOptions.SO_SNDBUF) {
+            return (T) getOption(SocketOptions.SO_SNDBUF);
+        } else if (name == StandardSocketOptions.SO_RCVBUF) {
+            return (T) getOption(SocketOptions.SO_RCVBUF);
+        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
+            return (T) getOption(SocketOptions.SO_REUSEADDR);
+        } else if (name == StandardSocketOptions.SO_REUSEPORT) {
+            return (T) getOption(SocketOptions.SO_REUSEPORT);
+        } else if (name == StandardSocketOptions.IP_TOS) {
+            return (T) getOption(SocketOptions.IP_TOS);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_IF) {
+            return (T) getOption(SocketOptions.IP_MULTICAST_IF2);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_TTL) {
+            return (T) ((Integer) getTimeToLive());
+        } else if (name == StandardSocketOptions.IP_MULTICAST_LOOP) {
+            return (T) getOption(SocketOptions.IP_MULTICAST_LOOP);
+        } else if (extendedOptions.isOptionSupported(name)) {
+            return (T) extendedOptions.getOption(fd, name);
+        } else {
+            throw new AssertionError("unknown option: " + name);
+        }
+    }
+
     protected abstract void datagramSocketCreate() throws SocketException;
     protected abstract void datagramSocketClose();
     protected abstract void socketSetOption(int opt, Object val)
--- a/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -35,12 +35,14 @@
 import java.security.PrivilegedExceptionAction;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Objects;
 import java.util.Set;
 
 import sun.net.ConnectionResetException;
 import sun.net.NetHooks;
 import sun.net.PlatformSocketImpl;
 import sun.net.ResourceManager;
+import sun.net.ext.ExtendedSocketOptions;
 import sun.net.util.SocketExceptions;
 
 /**
@@ -84,6 +86,9 @@
     */
     protected boolean stream;
 
+    /* whether this is a server or not */
+    final boolean isServer;
+
     /**
      * Load net library into runtime.
      */
@@ -112,27 +117,7 @@
     }
 
     AbstractPlainSocketImpl(boolean isServer) {
-        super(isServer);
-    }
-
-    /**
-     * Returns a set of SocketOptions supported by this impl and by this impl's
-     * socket (Socket or ServerSocket)
-     *
-     * @return a Set of SocketOptions
-     */
-    @Override
-    protected Set<SocketOption<?>> supportedOptions() {
-        Set<SocketOption<?>> options;
-        if (isReusePortAvailable()) {
-            options = new HashSet<>();
-            options.addAll(super.supportedOptions());
-            options.add(StandardSocketOptions.SO_REUSEPORT);
-            options = Collections.unmodifiableSet(options);
-        } else {
-            options = super.supportedOptions();
-        }
-        return options;
+        this.isServer = isServer;
     }
 
     /**
@@ -394,6 +379,121 @@
         }
     }
 
+    static final ExtendedSocketOptions extendedOptions =
+            ExtendedSocketOptions.getInstance();
+
+    private static final Set<SocketOption<?>> clientSocketOptions = clientSocketOptions();
+    private static final Set<SocketOption<?>> serverSocketOptions = serverSocketOptions();
+
+    private static Set<SocketOption<?>> clientSocketOptions() {
+        HashSet<SocketOption<?>> options = new HashSet<>();
+        options.add(StandardSocketOptions.SO_KEEPALIVE);
+        options.add(StandardSocketOptions.SO_SNDBUF);
+        options.add(StandardSocketOptions.SO_RCVBUF);
+        options.add(StandardSocketOptions.SO_REUSEADDR);
+        options.add(StandardSocketOptions.SO_LINGER);
+        options.add(StandardSocketOptions.IP_TOS);
+        options.add(StandardSocketOptions.TCP_NODELAY);
+        if (isReusePortAvailable())
+            options.add(StandardSocketOptions.SO_REUSEPORT);
+        options.addAll(ExtendedSocketOptions.clientSocketOptions());
+        return Collections.unmodifiableSet(options);
+    }
+
+    private static Set<SocketOption<?>> serverSocketOptions() {
+        HashSet<SocketOption<?>> options = new HashSet<>();
+        options.add(StandardSocketOptions.SO_RCVBUF);
+        options.add(StandardSocketOptions.SO_REUSEADDR);
+        options.add(StandardSocketOptions.IP_TOS);
+        if (isReusePortAvailable())
+            options.add(StandardSocketOptions.SO_REUSEPORT);
+        options.addAll(ExtendedSocketOptions.serverSocketOptions());
+        return Collections.unmodifiableSet(options);
+    }
+
+    @Override
+    protected Set<SocketOption<?>> supportedOptions() {
+        if (isServer)
+            return serverSocketOptions;
+        else
+            return clientSocketOptions;
+    }
+
+    @Override
+    protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
+        Objects.requireNonNull(name);
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
+
+        if (!name.type().isInstance(value))
+            throw new IllegalArgumentException("Invalid value '" + value + "'");
+
+        if (isClosedOrPending())
+            throw new SocketException("Socket closed");
+
+        if (name == StandardSocketOptions.SO_KEEPALIVE) {
+            setOption(SocketOptions.SO_KEEPALIVE, value);
+        } else if (name == StandardSocketOptions.SO_SNDBUF) {
+            if (((Integer)value).intValue() < 0)
+                throw new IllegalArgumentException("Invalid send buffer size:" + value);
+            setOption(SocketOptions.SO_SNDBUF, value);
+        } else if (name == StandardSocketOptions.SO_RCVBUF) {
+            if (((Integer)value).intValue() < 0)
+                throw new IllegalArgumentException("Invalid recv buffer size:" + value);
+            setOption(SocketOptions.SO_RCVBUF, value);
+        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
+            setOption(SocketOptions.SO_REUSEADDR, value);
+        } else if (name == StandardSocketOptions.SO_REUSEPORT) {
+            setOption(SocketOptions.SO_REUSEPORT, value);
+        } else if (name == StandardSocketOptions.SO_LINGER ) {
+            setOption(SocketOptions.SO_LINGER, value);
+        } else if (name == StandardSocketOptions.IP_TOS) {
+            int i = ((Integer)value).intValue();
+            if (i < 0 || i > 255)
+                throw new IllegalArgumentException("Invalid IP_TOS value: " + value);
+            setOption(SocketOptions.IP_TOS, value);
+        } else if (name == StandardSocketOptions.TCP_NODELAY) {
+            setOption(SocketOptions.TCP_NODELAY, value);
+        } else if (extendedOptions.isOptionSupported(name)) {
+            extendedOptions.setOption(fd, name, value);
+        } else {
+            throw new AssertionError("unknown option: " + name);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected <T> T getOption(SocketOption<T> name) throws IOException {
+        Objects.requireNonNull(name);
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
+
+        if (isClosedOrPending())
+            throw new SocketException("Socket closed");
+
+        if (name == StandardSocketOptions.SO_KEEPALIVE) {
+            return (T)getOption(SocketOptions.SO_KEEPALIVE);
+        } else if (name == StandardSocketOptions.SO_SNDBUF) {
+            return (T)getOption(SocketOptions.SO_SNDBUF);
+        } else if (name == StandardSocketOptions.SO_RCVBUF) {
+            return (T)getOption(SocketOptions.SO_RCVBUF);
+        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
+            return (T)getOption(SocketOptions.SO_REUSEADDR);
+        } else if (name == StandardSocketOptions.SO_REUSEPORT) {
+            return (T)getOption(SocketOptions.SO_REUSEPORT);
+        } else if (name == StandardSocketOptions.SO_LINGER) {
+            return (T)getOption(SocketOptions.SO_LINGER);
+        } else if (name == StandardSocketOptions.IP_TOS) {
+            return (T)getOption(SocketOptions.IP_TOS);
+        } else if (name == StandardSocketOptions.TCP_NODELAY) {
+            return (T)getOption(SocketOptions.TCP_NODELAY);
+        } else if (extendedOptions.isOptionSupported(name)) {
+            return (T) extendedOptions.getOption(fd, name);
+        } else {
+            throw new AssertionError("unknown option: " + name);
+        }
+    }
+
     /**
      * The workhorse of the connection operation.  Tries several times to
      * establish a connection to the given <host, port>.  If unsuccessful,
--- a/src/java.base/share/classes/java/net/DatagramSocket.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/net/DatagramSocket.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 import java.nio.channels.DatagramChannel;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
+import java.util.Objects;
 import java.util.Set;
 import java.util.Collections;
 
@@ -1343,6 +1344,9 @@
     public <T> DatagramSocket setOption(SocketOption<T> name, T value)
         throws IOException
     {
+        Objects.requireNonNull(name);
+        if (isClosed())
+            throw new SocketException("Socket is closed");
         getImpl().setOption(name, value);
         return this;
     }
@@ -1371,6 +1375,9 @@
      * @since 9
      */
     public <T> T getOption(SocketOption<T> name) throws IOException {
+        Objects.requireNonNull(name);
+        if (isClosed())
+            throw new SocketException("Socket is closed");
         return getImpl().getOption(name);
     }
 
--- a/src/java.base/share/classes/java/net/DatagramSocketImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/net/DatagramSocketImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -265,123 +266,69 @@
     /**
      * Called to set a socket option.
      *
+     * @implSpec
+     * The default implementation of this method first checks that the given
+     * socket option {code name} is not null, then throws {@code
+     * UnsupportedOperationException}. Subclasses should override this method
+     * with an appropriate implementation.
+     *
      * @param <T> The type of the socket option value
      * @param name The socket option
-     *
      * @param value The value of the socket option. A value of {@code null}
      *              may be valid for some options.
      *
      * @throws UnsupportedOperationException if the DatagramSocketImpl does not
      *         support the option
-     *
+     * @throws IllegalArgumentException if the value is not valid for
+     *         the option
+     * @throws IOException if an I/O error occurs, or if the socket is closed
      * @throws NullPointerException if name is {@code null}
-     * @throws IOException if an I/O problem occurs while attempting to set the option
+     *
      * @since 9
      */
     protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
-        if (name == StandardSocketOptions.SO_SNDBUF) {
-            setOption(SocketOptions.SO_SNDBUF, value);
-        } else if (name == StandardSocketOptions.SO_RCVBUF) {
-            setOption(SocketOptions.SO_RCVBUF, value);
-        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
-            setOption(SocketOptions.SO_REUSEADDR, value);
-        } else if (name == StandardSocketOptions.SO_REUSEPORT &&
-            supportedOptions().contains(name)) {
-            setOption(SocketOptions.SO_REUSEPORT, value);
-        } else if (name == StandardSocketOptions.IP_TOS) {
-            setOption(SocketOptions.IP_TOS, value);
-        } else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
-            (getDatagramSocket() instanceof MulticastSocket)) {
-            setOption(SocketOptions.IP_MULTICAST_IF2, value);
-        } else if (name == StandardSocketOptions.IP_MULTICAST_TTL &&
-            (getDatagramSocket() instanceof MulticastSocket)) {
-            if (! (value instanceof Integer)) {
-                throw new IllegalArgumentException("not an integer");
-            }
-            setTimeToLive((Integer)value);
-        } else if (name == StandardSocketOptions.IP_MULTICAST_LOOP &&
-            (getDatagramSocket() instanceof MulticastSocket)) {
-            setOption(SocketOptions.IP_MULTICAST_LOOP, value);
-        } else {
-            throw new UnsupportedOperationException("unsupported option");
-        }
+        Objects.requireNonNull(name);
+        throw new UnsupportedOperationException("'" + name + "' not supported");
     }
 
     /**
      * Called to get a socket option.
      *
-     * @return the socket option
+     * @implSpec
+     * The default implementation of this method first checks that the given
+     * socket option {code name} is not null, then throws {@code
+     * UnsupportedOperationException}. Subclasses should override this method
+     * with an appropriate implementation.
+     *
      * @param <T> The type of the socket option value
      * @param name The socket option
+     * @return the socket option
      *
      * @throws UnsupportedOperationException if the DatagramSocketImpl does not
      *         support the option
-     *
+     * @throws IOException if an I/O error occurs, or if the socket is closed
      * @throws NullPointerException if name is {@code null}
-     * @throws IOException if an I/O problem occurs while attempting to set the option
      *
      * @since 9
      */
-    @SuppressWarnings("unchecked")
     protected <T> T getOption(SocketOption<T> name) throws IOException {
-        if (name == StandardSocketOptions.SO_SNDBUF) {
-            return (T) getOption(SocketOptions.SO_SNDBUF);
-        } else if (name == StandardSocketOptions.SO_RCVBUF) {
-            return (T) getOption(SocketOptions.SO_RCVBUF);
-        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
-            return (T) getOption(SocketOptions.SO_REUSEADDR);
-        } else if (name == StandardSocketOptions.SO_REUSEPORT &&
-            supportedOptions().contains(name)) {
-            return (T) getOption(SocketOptions.SO_REUSEPORT);
-        } else if (name == StandardSocketOptions.IP_TOS) {
-            return (T) getOption(SocketOptions.IP_TOS);
-        } else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
-            (getDatagramSocket() instanceof MulticastSocket)) {
-            return (T) getOption(SocketOptions.IP_MULTICAST_IF2);
-        } else if (name == StandardSocketOptions.IP_MULTICAST_TTL &&
-            (getDatagramSocket() instanceof MulticastSocket)) {
-            Integer ttl = getTimeToLive();
-            return (T)ttl;
-        } else if (name == StandardSocketOptions.IP_MULTICAST_LOOP &&
-            (getDatagramSocket() instanceof MulticastSocket)) {
-            return (T) getOption(SocketOptions.IP_MULTICAST_LOOP);
-        } else {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-    }
-
-    private static final Set<SocketOption<?>> dgSocketOptions;
-
-    private static final Set<SocketOption<?>> mcSocketOptions;
-
-    static {
-        dgSocketOptions = Set.of(StandardSocketOptions.SO_SNDBUF,
-                                 StandardSocketOptions.SO_RCVBUF,
-                                 StandardSocketOptions.SO_REUSEADDR,
-                                 StandardSocketOptions.IP_TOS);
-
-        mcSocketOptions = Set.of(StandardSocketOptions.SO_SNDBUF,
-                                 StandardSocketOptions.SO_RCVBUF,
-                                 StandardSocketOptions.SO_REUSEADDR,
-                                 StandardSocketOptions.IP_TOS,
-                                 StandardSocketOptions.IP_MULTICAST_IF,
-                                 StandardSocketOptions.IP_MULTICAST_TTL,
-                                 StandardSocketOptions.IP_MULTICAST_LOOP);
+        Objects.requireNonNull(name);
+        throw new UnsupportedOperationException("'" + name + "' not supported");
     }
 
     /**
      * Returns a set of SocketOptions supported by this impl
      * and by this impl's socket (DatagramSocket or MulticastSocket)
      *
+     * @implSpec
+     * The default implementation of this method returns an empty set.
+     * Subclasses should override this method with an appropriate implementation.
+     *
      * @return a Set of SocketOptions
      *
      * @since 9
      */
     protected Set<SocketOption<?>> supportedOptions() {
-        if (getDatagramSocket() instanceof MulticastSocket) {
-            return mcSocketOptions;
-        } else {
-            return dgSocketOptions;
-        }
+        return Set.of();
     }
 }
--- a/src/java.base/share/classes/java/net/ServerSocket.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/net/ServerSocket.java	Thu May 30 19:49:55 2019 +0200
@@ -817,7 +817,8 @@
      * Returns the implementation address and implementation port of
      * this socket as a {@code String}.
      * <p>
-     * If there is a security manager set, its {@code checkConnect} method is
+     * If there is a security manager set, and this socket is
+     * {@linkplain #isBound bound}, its {@code checkConnect} method is
      * called with the local address and {@code -1} as its arguments to see
      * if the operation is allowed. If the operation is not allowed,
      * an {@code InetAddress} representing the
@@ -831,7 +832,7 @@
             return "ServerSocket[unbound]";
         InetAddress in;
         if (System.getSecurityManager() != null)
-            in = InetAddress.getLoopbackAddress();
+            in = getInetAddress();
         else
             in = impl.getInetAddress();
         return "ServerSocket[addr=" + in +
@@ -1025,6 +1026,9 @@
     public <T> ServerSocket setOption(SocketOption<T> name, T value)
         throws IOException
     {
+        Objects.requireNonNull(name);
+        if (isClosed())
+            throw new SocketException("Socket is closed");
         getImpl().setOption(name, value);
         return this;
     }
@@ -1053,6 +1057,9 @@
      * @since 9
      */
     public <T> T getOption(SocketOption<T> name) throws IOException {
+        Objects.requireNonNull(name);
+        if (isClosed())
+            throw new SocketException("Socket is closed");
         return getImpl().getOption(name);
     }
 
--- a/src/java.base/share/classes/java/net/Socket.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/net/Socket.java	Thu May 30 19:49:55 2019 +0200
@@ -33,6 +33,7 @@
 import java.nio.channels.SocketChannel;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Objects;
 import java.util.Set;
 import java.util.Collections;
 
@@ -1786,6 +1787,9 @@
      * @since 9
      */
     public <T> Socket setOption(SocketOption<T> name, T value) throws IOException {
+        Objects.requireNonNull(name);
+        if (isClosed())
+            throw new SocketException("Socket is closed");
         getImpl().setOption(name, value);
         return this;
     }
@@ -1815,6 +1819,9 @@
      */
     @SuppressWarnings("unchecked")
     public <T> T getOption(SocketOption<T> name) throws IOException {
+        Objects.requireNonNull(name);
+        if (isClosed())
+            throw new SocketException("Socket is closed");
         return getImpl().getOption(name);
     }
 
--- a/src/java.base/share/classes/java/net/SocketImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/net/SocketImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -25,33 +25,63 @@
 
 package java.net;
 
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.FileDescriptor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Objects;
 import java.util.Set;
 
+import sun.net.NetProperties;
 import sun.net.PlatformSocketImpl;
+import sun.nio.ch.NioSocketImpl;
 
 /**
  * The abstract class {@code SocketImpl} is a common superclass
  * of all classes that actually implement sockets. It is used to
  * create both client and server sockets.
- * <p>
- * A "plain" socket implements these methods exactly as
- * described, without attempting to go through a firewall or proxy.
+ *
+ * @implNote Client and server sockets created with the {@code Socket} and
+ * {@code SocketServer} public constructors create a system-default
+ * {@code SocketImpl}. The JDK historically used a {@code SocketImpl}
+ * implementation type named "PlainSocketImpl" that has since been replaced by a
+ * newer implementation. The JDK continues to ship with the older implementation
+ * to allow code to run that depends on unspecified behavior that differs between
+ * the old and new implementations. The old implementation will be used if the
+ * Java virtual machine is started with the system property {@systemProperty
+ * jdk.net.usePlainSocketImpl} set to use the old implementation. It may also be
+ * set in the JDK's network configuration file, located in {@code
+ * ${java.home}/conf/net.properties}. The value of the property is the string
+ * representation of a boolean. If set without a value then it defaults to {@code
+ * true}, hence running with {@code -Djdk.net.usePlainSocketImpl} or {@code
+ * -Djdk.net.usePlainSocketImpl=true} will configure the Java virtual machine
+ * to use the old implementation. The property and old implementation will be
+ * removed in a future version.
  *
  * @author  unascribed
  * @since   1.0
  */
 public abstract class SocketImpl implements SocketOptions {
+    private static final boolean USE_PLAINSOCKETIMPL = usePlainSocketImpl();
+
+    private static boolean usePlainSocketImpl() {
+        PrivilegedAction<String> pa = () -> NetProperties.get("jdk.net.usePlainSocketImpl");
+        String s = AccessController.doPrivileged(pa);
+        return (s != null) && !s.equalsIgnoreCase("false");
+    }
 
     /**
      * Creates an instance of platform's SocketImpl
      */
     @SuppressWarnings("unchecked")
     static <S extends SocketImpl & PlatformSocketImpl> S createPlatformSocketImpl(boolean server) {
-        return (S) new PlainSocketImpl(server);
+        if (USE_PLAINSOCKETIMPL) {
+            return (S) new PlainSocketImpl(server);
+        } else {
+            return (S) new NioSocketImpl(server);
+        }
     }
 
     /**
@@ -75,21 +105,9 @@
     protected int localport;
 
     /**
-     * Whether this is a server or not.
-     */
-    final boolean isServer;
-
-
-    SocketImpl(boolean isServer) {
-        this.isServer = isServer;
-    }
-
-    /**
      * Initialize a new instance of this class
      */
-    public SocketImpl() {
-        this.isServer = false;
-    }
+    public SocketImpl() { }
 
     /**
      * Creates either a stream or a datagram socket.
@@ -376,79 +394,54 @@
     /**
      * Called to set a socket option.
      *
+     * @implSpec
+     * The default implementation of this method first checks that the given
+     * socket option {code name} is not null, then throws {@code
+     * UnsupportedOperationException}. Subclasses should override this method
+     * with an appropriate implementation.
+     *
      * @param <T> The type of the socket option value
      * @param name The socket option
-     *
      * @param value The value of the socket option. A value of {@code null}
      *              may be valid for some options.
      *
      * @throws UnsupportedOperationException if the SocketImpl does not
      *         support the option
-     *
-     * @throws IOException if an I/O error occurs, or if the socket is closed.
+     * @throws IllegalArgumentException if the value is not valid for
+     *         the option
+     * @throws IOException if an I/O error occurs, or if the socket is closed
+     * @throws NullPointerException if name is {@code null}
      *
      * @since 9
      */
     protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
-        if (name == StandardSocketOptions.SO_KEEPALIVE && !isServer) {
-            setOption(SocketOptions.SO_KEEPALIVE, value);
-        } else if (name == StandardSocketOptions.SO_SNDBUF && !isServer) {
-            setOption(SocketOptions.SO_SNDBUF, value);
-        } else if (name == StandardSocketOptions.SO_RCVBUF) {
-            setOption(SocketOptions.SO_RCVBUF, value);
-        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
-            setOption(SocketOptions.SO_REUSEADDR, value);
-        } else if (name == StandardSocketOptions.SO_REUSEPORT &&
-            supportedOptions().contains(name)) {
-            setOption(SocketOptions.SO_REUSEPORT, value);
-        } else if (name == StandardSocketOptions.SO_LINGER && !isServer) {
-            setOption(SocketOptions.SO_LINGER, value);
-        } else if (name == StandardSocketOptions.IP_TOS) {
-            setOption(SocketOptions.IP_TOS, value);
-        } else if (name == StandardSocketOptions.TCP_NODELAY && !isServer) {
-            setOption(SocketOptions.TCP_NODELAY, value);
-        } else {
-            throw new UnsupportedOperationException("unsupported option");
-        }
+        Objects.requireNonNull(name);
+        throw new UnsupportedOperationException("'" + name + "' not supported");
     }
 
     /**
      * Called to get a socket option.
      *
+     * @implSpec
+     * The default implementation of this method first checks that the given
+     * socket option {code name} is not null, then throws {@code
+     * UnsupportedOperationException}. Subclasses should override this method
+     * with an appropriate implementation.
+     *
      * @param <T> The type of the socket option value
      * @param name The socket option
-     *
      * @return the value of the named option
      *
      * @throws UnsupportedOperationException if the SocketImpl does not
-     *         support the option.
-     *
-     * @throws IOException if an I/O error occurs, or if the socket is closed.
+     *         support the option
+     * @throws IOException if an I/O error occurs, or if the socket is closed
+     * @throws NullPointerException if name is {@code null}
      *
      * @since 9
      */
-    @SuppressWarnings("unchecked")
     protected <T> T getOption(SocketOption<T> name) throws IOException {
-        if (name == StandardSocketOptions.SO_KEEPALIVE && !isServer) {
-            return (T)getOption(SocketOptions.SO_KEEPALIVE);
-        } else if (name == StandardSocketOptions.SO_SNDBUF && !isServer) {
-            return (T)getOption(SocketOptions.SO_SNDBUF);
-        } else if (name == StandardSocketOptions.SO_RCVBUF) {
-            return (T)getOption(SocketOptions.SO_RCVBUF);
-        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
-            return (T)getOption(SocketOptions.SO_REUSEADDR);
-        } else if (name == StandardSocketOptions.SO_REUSEPORT &&
-            supportedOptions().contains(name)) {
-            return (T)getOption(SocketOptions.SO_REUSEPORT);
-        } else if (name == StandardSocketOptions.SO_LINGER && !isServer) {
-            return (T)getOption(SocketOptions.SO_LINGER);
-        } else if (name == StandardSocketOptions.IP_TOS) {
-            return (T)getOption(SocketOptions.IP_TOS);
-        } else if (name == StandardSocketOptions.TCP_NODELAY && !isServer) {
-            return (T)getOption(SocketOptions.TCP_NODELAY);
-        } else {
-            throw new UnsupportedOperationException("unsupported option");
-        }
+        Objects.requireNonNull(name);
+        throw new UnsupportedOperationException("'" + name + "' not supported");
     }
 
     /**
@@ -464,37 +457,19 @@
         } catch (IOException ignore) { }
     }
 
-    private static final Set<SocketOption<?>> socketOptions;
-
-    private static final Set<SocketOption<?>> serverSocketOptions;
-
-    static {
-        socketOptions = Set.of(StandardSocketOptions.SO_KEEPALIVE,
-                               StandardSocketOptions.SO_SNDBUF,
-                               StandardSocketOptions.SO_RCVBUF,
-                               StandardSocketOptions.SO_REUSEADDR,
-                               StandardSocketOptions.SO_LINGER,
-                               StandardSocketOptions.IP_TOS,
-                               StandardSocketOptions.TCP_NODELAY);
-
-        serverSocketOptions = Set.of(StandardSocketOptions.SO_RCVBUF,
-                                     StandardSocketOptions.SO_REUSEADDR,
-                                     StandardSocketOptions.IP_TOS);
-    }
-
     /**
      * Returns a set of SocketOptions supported by this impl
      * and by this impl's socket (Socket or ServerSocket)
      *
+     * @implSpec
+     * The default implementation of this method returns an empty set.
+     * Subclasses should override this method with an appropriate implementation.
+     *
      * @return a Set of SocketOptions
      *
      * @since 9
      */
     protected Set<SocketOption<?>> supportedOptions() {
-        if (!isServer) {
-            return socketOptions;
-        } else {
-            return serverSocketOptions;
-        }
+        return Set.of();
     }
 }
--- a/src/java.base/share/classes/java/nio/channels/AsynchronousChannelGroup.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/nio/channels/AsynchronousChannelGroup.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -70,7 +70,9 @@
  *   </thead>
  *   <tbody>
  *   <tr>
- *     <th scope="row"> {@code java.nio.channels.DefaultThreadPool.threadFactory} </th>
+ *     <th scope="row">
+ *       {@systemProperty java.nio.channels.DefaultThreadPool.threadFactory}
+ *     </th>
  *     <td> The value of this property is taken to be the fully-qualified name
  *     of a concrete {@link java.util.concurrent.ThreadFactory ThreadFactory}
  *     class. The class is loaded using the system class loader and instantiated.
@@ -81,7 +83,9 @@
  *     construction of the default group. </td>
  *   </tr>
  *   <tr>
- *     <th scope="row"> {@code java.nio.channels.DefaultThreadPool.initialSize} </th>
+ *     <th scope="row">
+ *       {@systemProperty java.nio.channels.DefaultThreadPool.initialSize}
+ *     </th>
  *     <td> The value of the {@code initialSize} parameter for the default
  *     group (see {@link #withCachedThreadPool withCachedThreadPool}).
  *     The value of the property is taken to be the {@code String}
--- a/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -138,10 +138,10 @@
      * <ol>
      *
      *   <li><p> If the system property
-     *   {@code java.nio.channels.spi.AsynchronousChannelProvider} is defined
-     *   then it is taken to be the fully-qualified name of a concrete provider class.
-     *   The class is loaded and instantiated; if this process fails then an
-     *   unspecified error is thrown.  </p></li>
+     *   {@systemProperty java.nio.channels.spi.AsynchronousChannelProvider} is
+     *   defined then it is taken to be the fully-qualified name of a concrete
+     *   provider class. The class is loaded and instantiated; if this process
+     *   fails then an unspecified error is thrown.  </p></li>
      *
      *   <li><p> If a provider class has been installed in a jar file that is
      *   visible to the system class loader, and that jar file contains a
--- a/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -143,10 +143,10 @@
      * <ol>
      *
      *   <li><p> If the system property
-     *   {@code java.nio.channels.spi.SelectorProvider} is defined then it is
-     *   taken to be the fully-qualified name of a concrete provider class.
-     *   The class is loaded and instantiated; if this process fails then an
-     *   unspecified error is thrown.  </p></li>
+     *   {@systemProperty java.nio.channels.spi.SelectorProvider} is defined
+     *   then it is taken to be the fully-qualified name of a concrete provider
+     *   class. The class is loaded and instantiated; if this process fails then
+     *   an unspecified error is thrown.  </p></li>
      *
      *   <li><p> If a provider class has been installed in a jar file that is
      *   visible to the system class loader, and that jar file contains a
--- a/src/java.base/share/classes/java/nio/charset/Charset.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/nio/charset/Charset.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -67,8 +67,7 @@
  * concurrent threads.
  *
  *
- * <a id="names"></a><a id="charenc"></a>
- * <h2>Charset names</h2>
+ * <h2><a id="names">Charset names</a></h2>
  *
  * <p> Charsets are named by strings composed of the following characters:
  *
@@ -138,12 +137,11 @@
  * previous canonical name be made into an alias.
  *
  *
- * <h2>Standard charsets</h2>
+ * <h2><a id="standard">Standard charsets</a></h2>
  *
  *
- *
- * <p><a id="standard">Every implementation of the Java platform is required to support the
- * following standard charsets.</a>  Consult the release documentation for your
+ * <p> Every implementation of the Java platform is required to support the
+ * following standard charsets.  Consult the release documentation for your
  * implementation to see if any other charsets are supported.  The behavior
  * of such optional charsets may differ between implementations.
  *
@@ -217,7 +215,7 @@
  * determined during virtual-machine startup and typically depends upon the
  * locale and charset being used by the underlying operating system. </p>
  *
- * <p>The {@link StandardCharsets} class defines constants for each of the
+ * <p> The {@link StandardCharsets} class defines constants for each of the
  * standard charsets.
  *
  * <h2>Terminology</h2>
--- a/src/java.base/share/classes/java/nio/charset/StandardCharsets.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/nio/charset/StandardCharsets.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * 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 @@
 package java.nio.charset;
 
 /**
- * Constant definitions for the standard {@link Charset Charsets}. These
+ * Constant definitions for the standard {@link Charset charsets}. These
  * charsets are guaranteed to be available on every implementation of the Java
  * platform.
  *
@@ -44,29 +44,34 @@
     }
 
     /**
-     * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
-     * Unicode character set
+     * Seven-bit ASCII, also known as ISO646-US, also known as the
+     * Basic Latin block of the Unicode character set.
      */
     public static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE;
+
     /**
-     * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
+     * ISO Latin Alphabet {@literal No. 1}, also known as ISO-LATIN-1.
      */
     public static final Charset ISO_8859_1 = sun.nio.cs.ISO_8859_1.INSTANCE;
+
     /**
-     * Eight-bit UCS Transformation Format
+     * Eight-bit UCS Transformation Format.
      */
     public static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE;
+
     /**
-     * Sixteen-bit UCS Transformation Format, big-endian byte order
+     * Sixteen-bit UCS Transformation Format, big-endian byte order.
      */
     public static final Charset UTF_16BE = new sun.nio.cs.UTF_16BE();
+
     /**
-     * Sixteen-bit UCS Transformation Format, little-endian byte order
+     * Sixteen-bit UCS Transformation Format, little-endian byte order.
      */
     public static final Charset UTF_16LE = new sun.nio.cs.UTF_16LE();
+
     /**
      * Sixteen-bit UCS Transformation Format, byte order identified by an
-     * optional byte-order mark
+     * optional byte-order mark.
      */
     public static final Charset UTF_16 = new sun.nio.cs.UTF_16();
 }
--- a/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -85,7 +85,7 @@
  * provides access to the file systems accessible to the Java virtual machine.
  * The {@link FileSystems} class defines how file system providers are located
  * and loaded. The default provider is typically a system-default provider but
- * may be overridden if the system property {@code
+ * may be overridden if the system property {@systemProperty
  * java.nio.file.spi.DefaultFileSystemProvider} is set. In that case, the
  * provider has a one argument constructor whose formal parameter type is {@code
  * FileSystemProvider}. All other providers have a zero argument constructor
--- a/src/java.base/share/classes/java/util/ArrayList.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/util/ArrayList.java	Thu May 30 19:49:55 2019 +0200
@@ -1696,6 +1696,7 @@
     @Override
     public void replaceAll(UnaryOperator<E> operator) {
         replaceAllRange(operator, 0, size);
+        // TODO(8203662): remove increment of modCount from ...
         modCount++;
     }
 
--- a/src/java.base/share/classes/java/util/Vector.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/util/Vector.java	Thu May 30 19:49:55 2019 +0200
@@ -1369,6 +1369,7 @@
             es[i] = operator.apply(elementAt(es, i));
         if (modCount != expectedModCount)
             throw new ConcurrentModificationException();
+        // TODO(8203662): remove increment of modCount from ...
         modCount++;
     }
 
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Thu May 30 19:49:55 2019 +0200
@@ -1712,9 +1712,8 @@
         Map<?,?> m = (Map<?,?>) o;
         try {
             Comparator<? super K> cmp = comparator;
-            @SuppressWarnings("unchecked")
-            Iterator<Map.Entry<?,?>> it =
-                (Iterator<Map.Entry<?,?>>)m.entrySet().iterator();
+            // See JDK-8223553 for Iterator type wildcard rationale
+            Iterator<? extends Map.Entry<?,?>> it = m.entrySet().iterator();
             if (m instanceof SortedMap &&
                 ((SortedMap<?,?>)m).comparator() == cmp) {
                 Node<K,V> b, n;
--- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Thu May 30 19:49:55 2019 +0200
@@ -867,8 +867,8 @@
                     growArray(true);
                 else {
                     phase = 0; // full volatile unlock
-                    if (a[m & (s - 1)] == null)
-                        signal = true;   // was empty
+                    if (((s - base) & ~1) == 0) // size 0 or 1
+                        signal = true;
                 }
             }
             return signal;
@@ -2667,13 +2667,13 @@
     }
 
     /**
-     * Returns an estimate of the total number of tasks stolen from
-     * one thread's work queue by another. The reported value
-     * underestimates the actual total number of steals when the pool
-     * is not quiescent. This value may be useful for monitoring and
-     * tuning fork/join programs: in general, steal counts should be
-     * high enough to keep threads busy, but low enough to avoid
-     * overhead and contention across threads.
+     * Returns an estimate of the total number of completed tasks that
+     * were executed by a thread other than their submitter. The
+     * reported value underestimates the actual total number of steals
+     * when the pool is not quiescent. This value may be useful for
+     * monitoring and tuning fork/join programs: in general, steal
+     * counts should be high enough to keep threads busy, but low
+     * enough to avoid overhead and contention across threads.
      *
      * @return the number of steals
      */
--- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Thu May 30 19:49:55 2019 +0200
@@ -360,7 +360,7 @@
      * Returns the current value of this {@code AtomicInteger} as a
      * {@code long} after a widening primitive conversion,
      * with memory effects as specified by {@link VarHandle#getVolatile}.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public long longValue() {
         return (long)get();
@@ -370,7 +370,7 @@
      * Returns the current value of this {@code AtomicInteger} as a
      * {@code float} after a widening primitive conversion,
      * with memory effects as specified by {@link VarHandle#getVolatile}.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public float floatValue() {
         return (float)get();
@@ -380,7 +380,7 @@
      * Returns the current value of this {@code AtomicInteger} as a
      * {@code double} after a widening primitive conversion,
      * with memory effects as specified by {@link VarHandle#getVolatile}.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public double doubleValue() {
         return (double)get();
--- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java	Thu May 30 19:49:55 2019 +0200
@@ -364,7 +364,7 @@
      * Returns the current value of this {@code AtomicLong} as an {@code int}
      * after a narrowing primitive conversion,
      * with memory effects as specified by {@link VarHandle#getVolatile}.
-     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @jls 5.1.3 Narrowing Primitive Conversion
      */
     public int intValue() {
         return (int)get();
@@ -383,7 +383,7 @@
      * Returns the current value of this {@code AtomicLong} as a {@code float}
      * after a widening primitive conversion,
      * with memory effects as specified by {@link VarHandle#getVolatile}.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public float floatValue() {
         return (float)get();
@@ -393,7 +393,7 @@
      * Returns the current value of this {@code AtomicLong} as a {@code double}
      * after a widening primitive conversion,
      * with memory effects as specified by {@link VarHandle#getVolatile}.
-     * @jls 5.1.2 Widening Primitive Conversions
+     * @jls 5.1.2 Widening Primitive Conversion
      */
     public double doubleValue() {
         return (double)get();
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Thu May 30 19:49:55 2019 +0200
@@ -3271,28 +3271,33 @@
         case '+':
             return curly(prev, 1);
         case '{':
-            ch = temp[cursor+1];
+            ch = skip();
             if (ASCII.isDigit(ch)) {
-                skip();
-                int cmin = 0;
-                do {
-                    cmin = cmin * 10 + (ch - '0');
-                } while (ASCII.isDigit(ch = read()));
-                int cmax = cmin;
-                if (ch == ',') {
-                    ch = read();
-                    cmax = MAX_REPS;
-                    if (ch != '}') {
-                        cmax = 0;
-                        while (ASCII.isDigit(ch)) {
-                            cmax = cmax * 10 + (ch - '0');
-                            ch = read();
+                int cmin = 0, cmax;
+                try {
+                    do {
+                        cmin = Math.addExact(Math.multiplyExact(cmin, 10),
+                                             ch - '0');
+                    } while (ASCII.isDigit(ch = read()));
+                    cmax = cmin;
+                    if (ch == ',') {
+                        ch = read();
+                        cmax = MAX_REPS;
+                        if (ch != '}') {
+                            cmax = 0;
+                            while (ASCII.isDigit(ch)) {
+                                cmax = Math.addExact(Math.multiplyExact(cmax, 10),
+                                                     ch - '0');
+                                ch = read();
+                            }
                         }
                     }
+                } catch (ArithmeticException ae) {
+                    throw error("Illegal repetition range");
                 }
                 if (ch != '}')
                     throw error("Unclosed counted closure");
-                if (((cmin) | (cmax) | (cmax - cmin)) < 0)
+                if (cmax < cmin)
                     throw error("Illegal repetition range");
                 Curly curly;
                 ch = peek();
--- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Thu May 30 19:49:55 2019 +0200
@@ -190,10 +190,11 @@
             throw new IllegalArgumentException("Fragment component present");
         }
         String path = uri.getPath();
-        if (path == null || path.charAt(0) != '/') {
+        if (path == null || path.charAt(0) != '/' || path.contains("..")) {
             throw new IllegalArgumentException("Invalid path component");
         }
-        return getTheFileSystem().getPath(path);
+
+        return getTheFileSystem().getPath("/modules" + path);
     }
 
     private FileSystem getTheFileSystem() {
--- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java	Thu May 30 19:49:55 2019 +0200
@@ -25,6 +25,7 @@
 package jdk.internal.jrtfs;
 
 import java.io.File;
+import java.io.IOError;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -170,7 +171,16 @@
     @Override
     public final URI toUri() {
         try {
-            return new URI("jrt", toAbsolutePath().path, null);
+            String p = toAbsolutePath().path;
+            if (!p.startsWith("/modules") || p.contains("..")) {
+                throw new IOError(new RuntimeException(p + " cannot be represented as URI"));
+            }
+
+            p = p.substring("/modules".length());
+            if (p.isEmpty()) {
+                p = "/";
+            }
+            return new URI("jrt", p, null);
         } catch (URISyntaxException ex) {
             throw new AssertionError(ex);
         }
--- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -166,6 +166,8 @@
 \                      configuration and continue\n\
 \    -Xss<size>        set java thread stack size\n\
 \    -Xverify          sets the mode of the bytecode verifier\n\
+\                      Note that option -Xverify:none is deprecated and\n\
+\                      may be removed in a future release.\n\
 \    --add-reads <module>=<target-module>(,<target-module>)*\n\
 \                      updates <module> to read <target-module>, regardless\n\
 \                      of module declaration. \n\
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -222,6 +222,8 @@
         Objects.requireNonNull(name);
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
+        if (!name.type().isInstance(value))
+            throw new IllegalArgumentException("Invalid value '" + value + "'");
 
         synchronized (stateLock) {
             ensureOpen();
@@ -236,8 +238,6 @@
             }
 
             if (name == StandardSocketOptions.IP_MULTICAST_IF) {
-                if (value == null)
-                    throw new IllegalArgumentException("Cannot set IP_MULTICAST_IF to 'null'");
                 NetworkInterface interf = (NetworkInterface)value;
                 if (family == StandardProtocolFamily.INET6) {
                     int index = interf.getIndex();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -0,0 +1,1283 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.ch;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ProtocolFamily;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketOption;
+import java.net.SocketTimeoutException;
+import java.net.StandardProtocolFamily;
+import java.net.StandardSocketOptions;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+import jdk.internal.ref.CleanerFactory;
+import sun.net.ConnectionResetException;
+import sun.net.NetHooks;
+import sun.net.PlatformSocketImpl;
+import sun.net.ResourceManager;
+import sun.net.ext.ExtendedSocketOptions;
+import sun.net.util.SocketExceptions;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+/**
+ * NIO based SocketImpl.
+ *
+ * This implementation attempts to be compatible with legacy PlainSocketImpl,
+ * including behavior and exceptions that are not specified by SocketImpl.
+ *
+ * The underlying socket used by this SocketImpl is initially configured
+ * blocking. If the connect method is used to establish a connection with a
+ * timeout then the socket is configured non-blocking for the connect attempt,
+ * and then restored to blocking mode when the connection is established.
+ * If the accept or read methods are used with a timeout then the socket is
+ * configured non-blocking and is never restored. When in non-blocking mode,
+ * operations that don't complete immediately will poll the socket and preserve
+ * the semantics of blocking operations.
+ */
+
+public final class NioSocketImpl extends SocketImpl implements PlatformSocketImpl {
+    private static final NativeDispatcher nd = new SocketDispatcher();
+
+    // The maximum number of bytes to read/write per syscall to avoid needing
+    // a huge buffer from the temporary buffer cache
+    private static final int MAX_BUFFER_SIZE = 128 * 1024;
+
+    // true if this is a SocketImpl for a ServerSocket
+    private final boolean server;
+
+    // Lock held when reading (also used when accepting or connecting)
+    private final ReentrantLock readLock = new ReentrantLock();
+
+    // Lock held when writing
+    private final ReentrantLock writeLock = new ReentrantLock();
+
+    // The stateLock for read/changing state
+    private final Object stateLock = new Object();
+    private static final int ST_NEW = 0;
+    private static final int ST_UNCONNECTED = 1;
+    private static final int ST_CONNECTING = 2;
+    private static final int ST_CONNECTED = 3;
+    private static final int ST_CLOSING = 4;
+    private static final int ST_CLOSED = 5;
+    private volatile int state;  // need stateLock to change
+
+    // set by SocketImpl.create, protected by stateLock
+    private boolean stream;
+    private FileDescriptorCloser closer;
+
+    // set to true when the socket is in non-blocking mode
+    private volatile boolean nonBlocking;
+
+    // used by connect/read/write/accept, protected by stateLock
+    private long readerThread;
+    private long writerThread;
+
+    // used when SO_REUSEADDR is emulated, protected by stateLock
+    private boolean isReuseAddress;
+
+    // read or accept timeout in millis
+    private volatile int timeout;
+
+    // flags to indicate if the connection is shutdown for input and output
+    private volatile boolean isInputClosed;
+    private volatile boolean isOutputClosed;
+
+    // used by read to emulate legacy behavior, protected by readLock
+    private boolean readEOF;
+    private boolean connectionReset;
+
+    /**
+     * Creates an instance of this SocketImpl.
+     * @param server true if this is a SocketImpl for a ServerSocket
+     */
+    public NioSocketImpl(boolean server) {
+        this.server = server;
+    }
+
+    /**
+     * Returns true if the socket is open.
+     */
+    private boolean isOpen() {
+        return state < ST_CLOSING;
+    }
+
+    /**
+     * Throws SocketException if the socket is not open.
+     */
+    private void ensureOpen() throws SocketException {
+        int state = this.state;
+        if (state == ST_NEW)
+            throw new SocketException("Socket not created");
+        if (state >= ST_CLOSING)
+            throw new SocketException("Socket closed");
+    }
+
+    /**
+     * Throws SocketException if the socket is not open and connected.
+     */
+    private void ensureOpenAndConnected() throws SocketException {
+        int state = this.state;
+        if (state < ST_CONNECTED)
+            throw new SocketException("Not connected");
+        if (state > ST_CONNECTED)
+            throw new SocketException("Socket closed");
+    }
+
+    /**
+     * Disables the current thread for scheduling purposes until the socket is
+     * ready for I/O, or is asynchronously closed, for up to the specified
+     * waiting time.
+     * @throws IOException if an I/O error occurs
+     */
+    private void park(FileDescriptor fd, int event, long nanos) throws IOException {
+        long millis;
+        if (nanos == 0) {
+            millis = -1;
+        } else {
+            millis = NANOSECONDS.toMillis(nanos);
+        }
+        Net.poll(fd, event, millis);
+    }
+
+    /**
+     * Disables the current thread for scheduling purposes until the socket is
+     * ready for I/O or is asynchronously closed.
+     * @throws IOException if an I/O error occurs
+     */
+    private void park(FileDescriptor fd, int event) throws IOException {
+        park(fd, event, 0);
+    }
+
+    /**
+     * Configures the socket to blocking mode. This method is a no-op if the
+     * socket is already in blocking mode.
+     * @throws IOException if closed or there is an I/O error changing the mode
+     */
+    private void configureBlocking(FileDescriptor fd) throws IOException {
+        assert readLock.isHeldByCurrentThread();
+        if (nonBlocking) {
+            synchronized (stateLock) {
+                ensureOpen();
+                IOUtil.configureBlocking(fd, true);
+                nonBlocking = false;
+            }
+        }
+    }
+
+    /**
+     * Configures the socket to non-blocking mode. This method is a no-op if the
+     * socket is already in non-blocking mode.
+     * @throws IOException if closed or there is an I/O error changing the mode
+     */
+    private void configureNonBlocking(FileDescriptor fd) throws IOException {
+        assert readLock.isHeldByCurrentThread();
+        if (!nonBlocking) {
+            synchronized (stateLock) {
+                ensureOpen();
+                IOUtil.configureBlocking(fd, false);
+                nonBlocking = true;
+            }
+        }
+    }
+
+    /**
+     * Marks the beginning of a read operation that might block.
+     * @throws SocketException if the socket is closed or not connected
+     */
+    private FileDescriptor beginRead() throws SocketException {
+        synchronized (stateLock) {
+            ensureOpenAndConnected();
+            readerThread = NativeThread.current();
+            return fd;
+        }
+    }
+
+    /**
+     * Marks the end of a read operation that may have blocked.
+     * @throws SocketException is the socket is closed
+     */
+    private void endRead(boolean completed) throws SocketException {
+        synchronized (stateLock) {
+            readerThread = 0;
+            int state = this.state;
+            if (state == ST_CLOSING)
+                tryFinishClose();
+            if (!completed && state >= ST_CLOSING)
+                throw new SocketException("Socket closed");
+        }
+    }
+
+    /**
+     * Attempts to read bytes from the socket into the given byte array.
+     */
+    private int tryRead(FileDescriptor fd, byte[] b, int off, int len)
+        throws IOException
+    {
+        ByteBuffer dst = Util.getTemporaryDirectBuffer(len);
+        assert dst.position() == 0;
+        try {
+            int n = nd.read(fd, ((DirectBuffer)dst).address(), len);
+            if (n > 0) {
+                dst.get(b, off, n);
+            }
+            return n;
+        } finally {
+            Util.offerFirstTemporaryDirectBuffer(dst);
+        }
+    }
+
+    /**
+     * Reads bytes from the socket into the given byte array with a timeout.
+     * @throws SocketTimeoutException if the read timeout elapses
+     */
+    private int timedRead(FileDescriptor fd, byte[] b, int off, int len, long nanos)
+        throws IOException
+    {
+        long startNanos = System.nanoTime();
+        int n = tryRead(fd, b, off, len);
+        while (n == IOStatus.UNAVAILABLE && isOpen()) {
+            long remainingNanos = nanos - (System.nanoTime() - startNanos);
+            if (remainingNanos <= 0) {
+                throw new SocketTimeoutException("Read timed out");
+            }
+            park(fd, Net.POLLIN, remainingNanos);
+            n = tryRead(fd, b, off, len);
+        }
+        return n;
+    }
+
+    /**
+     * Reads bytes from the socket into the given byte array.
+     * @return the number of bytes read or -1 at EOF
+     * @throws SocketException if the socket is closed or a socket I/O error occurs
+     * @throws SocketTimeoutException if the read timeout elapses
+     */
+    private int implRead(byte[] b, int off, int len) throws IOException {
+        int n = 0;
+        FileDescriptor fd = beginRead();
+        try {
+            if (connectionReset)
+                throw new SocketException("Connection reset");
+            if (isInputClosed)
+                return -1;
+            int timeout = this.timeout;
+            if (timeout > 0) {
+                // read with timeout
+                configureNonBlocking(fd);
+                n = timedRead(fd, b, off, len, MILLISECONDS.toNanos(timeout));
+            } else {
+                // read, no timeout
+                n = tryRead(fd, b, off, len);
+                while (IOStatus.okayToRetry(n) && isOpen()) {
+                    park(fd, Net.POLLIN);
+                    n = tryRead(fd, b, off, len);
+                }
+            }
+            return n;
+        } catch (SocketTimeoutException e) {
+            throw e;
+        } catch (ConnectionResetException e) {
+            connectionReset = true;
+            throw new SocketException("Connection reset");
+        } catch (IOException ioe) {
+            throw new SocketException(ioe.getMessage());
+        } finally {
+            endRead(n > 0);
+        }
+    }
+
+    /**
+     * Reads bytes from the socket into the given byte array.
+     * @return the number of bytes read or -1 at EOF
+     * @throws IndexOutOfBoundsException if the bound checks fail
+     * @throws SocketException if the socket is closed or a socket I/O error occurs
+     * @throws SocketTimeoutException if the read timeout elapses
+     */
+    private int read(byte[] b, int off, int len) throws IOException {
+        Objects.checkFromIndexSize(off, len, b.length);
+        if (len == 0) {
+            return 0;
+        } else {
+            readLock.lock();
+            try {
+                // emulate legacy behavior to return -1, even if socket is closed
+                if (readEOF)
+                    return -1;
+                // read up to MAX_BUFFER_SIZE bytes
+                int size = Math.min(len, MAX_BUFFER_SIZE);
+                int n = implRead(b, off, size);
+                if (n == -1)
+                    readEOF = true;
+                return n;
+            } finally {
+                readLock.unlock();
+            }
+        }
+    }
+
+    /**
+     * Marks the beginning of a write operation that might block.
+     * @throws SocketException if the socket is closed or not connected
+     */
+    private FileDescriptor beginWrite() throws SocketException {
+        synchronized (stateLock) {
+            ensureOpenAndConnected();
+            writerThread = NativeThread.current();
+            return fd;
+        }
+    }
+
+    /**
+     * Marks the end of a write operation that may have blocked.
+     * @throws SocketException is the socket is closed
+     */
+    private void endWrite(boolean completed) throws SocketException {
+        synchronized (stateLock) {
+            writerThread = 0;
+            int state = this.state;
+            if (state == ST_CLOSING)
+                tryFinishClose();
+            if (!completed && state >= ST_CLOSING)
+                throw new SocketException("Socket closed");
+        }
+    }
+
+    /**
+     * Attempts to write a sequence of bytes to the socket from the given
+     * byte array.
+     */
+    private int tryWrite(FileDescriptor fd, byte[] b, int off, int len)
+        throws IOException
+    {
+        ByteBuffer src = Util.getTemporaryDirectBuffer(len);
+        assert src.position() == 0;
+        try {
+            src.put(b, off, len);
+            return nd.write(fd, ((DirectBuffer)src).address(), len);
+        } finally {
+            Util.offerFirstTemporaryDirectBuffer(src);
+        }
+    }
+
+    /**
+     * Writes a sequence of bytes to the socket from the given byte array.
+     * @return the number of bytes written
+     * @throws SocketException if the socket is closed or a socket I/O error occurs
+     */
+    private int implWrite(byte[] b, int off, int len) throws IOException {
+        int n = 0;
+        FileDescriptor fd = beginWrite();
+        try {
+            n = tryWrite(fd, b, off, len);
+            while (IOStatus.okayToRetry(n) && isOpen()) {
+                park(fd, Net.POLLOUT);
+                n = tryWrite(fd, b, off, len);
+            }
+            return n;
+        } catch (IOException ioe) {
+            throw new SocketException(ioe.getMessage());
+        } finally {
+            endWrite(n > 0);
+        }
+    }
+
+    /**
+     * Writes a sequence of bytes to the socket from the given byte array.
+     * @throws SocketException if the socket is closed or a socket I/O error occurs
+     */
+    private void write(byte[] b, int off, int len) throws IOException {
+        Objects.checkFromIndexSize(off, len, b.length);
+        if (len > 0) {
+            writeLock.lock();
+            try {
+                int pos = off;
+                int end = off + len;
+                while (pos < end) {
+                    // write up to MAX_BUFFER_SIZE bytes
+                    int size = Math.min((end - pos), MAX_BUFFER_SIZE);
+                    int n = implWrite(b, pos, size);
+                    pos += n;
+                }
+            } finally {
+                writeLock.unlock();
+            }
+        }
+    }
+
+    /**
+     * Creates the socket.
+     * @param stream {@code true} for a streams socket
+     */
+    @Override
+    protected void create(boolean stream) throws IOException {
+        synchronized (stateLock) {
+            if (state != ST_NEW)
+                throw new IOException("Already created");
+            if (!stream)
+                ResourceManager.beforeUdpCreate();
+            FileDescriptor fd;
+            try {
+                if (server) {
+                    assert stream;
+                    fd = Net.serverSocket(true);
+                } else {
+                    fd = Net.socket(stream);
+                }
+            } catch (IOException ioe) {
+                if (!stream)
+                    ResourceManager.afterUdpClose();
+                throw ioe;
+            }
+            this.fd = fd;
+            this.stream = stream;
+            this.closer = FileDescriptorCloser.create(this);
+            this.state = ST_UNCONNECTED;
+        }
+    }
+
+    /**
+     * Marks the beginning of a connect operation that might block.
+     * @throws SocketException if the socket is closed or already connected
+     */
+    private FileDescriptor beginConnect(InetAddress address, int port)
+        throws IOException
+    {
+        synchronized (stateLock) {
+            int state = this.state;
+            if (state != ST_UNCONNECTED) {
+                if (state == ST_NEW)
+                    throw new SocketException("Not created");
+                if (state == ST_CONNECTING)
+                    throw new SocketException("Connection in progress");
+                if (state == ST_CONNECTED)
+                    throw new SocketException("Already connected");
+                if (state >= ST_CLOSING)
+                    throw new SocketException("Socket closed");
+                assert false;
+            }
+            this.state = ST_CONNECTING;
+
+            // invoke beforeTcpConnect hook if not already bound
+            if (localport == 0) {
+                NetHooks.beforeTcpConnect(fd, address, port);
+            }
+
+            // save the remote address/port
+            this.address = address;
+            this.port = port;
+
+            readerThread = NativeThread.current();
+            return fd;
+        }
+    }
+
+    /**
+     * Marks the end of a connect operation that may have blocked.
+     * @throws SocketException is the socket is closed
+     */
+    private void endConnect(FileDescriptor fd, boolean completed) throws IOException {
+        synchronized (stateLock) {
+            readerThread = 0;
+            int state = this.state;
+            if (state == ST_CLOSING)
+                tryFinishClose();
+            if (completed && state == ST_CONNECTING) {
+                this.state = ST_CONNECTED;
+                localport = Net.localAddress(fd).getPort();
+            } else if (!completed && state >= ST_CLOSING) {
+                throw new SocketException("Socket closed");
+            }
+        }
+    }
+
+    /**
+     * Waits for a connection attempt to finish with a timeout
+     * @throws SocketTimeoutException if the connect timeout elapses
+     */
+    private boolean timedFinishConnect(FileDescriptor fd, long nanos) throws IOException {
+        long startNanos = System.nanoTime();
+        boolean polled = Net.pollConnectNow(fd);
+        while (!polled && isOpen()) {
+            long remainingNanos = nanos - (System.nanoTime() - startNanos);
+            if (remainingNanos <= 0) {
+                throw new SocketTimeoutException("Connect timed out");
+            }
+            park(fd, Net.POLLOUT, remainingNanos);
+            polled = Net.pollConnectNow(fd);
+        }
+        return polled && isOpen();
+    }
+
+    /**
+     * Attempts to establish a connection to the given socket address with a
+     * timeout. Closes the socket if connection cannot be established.
+     * @throws IOException if the address is not a resolved InetSocketAddress or
+     *         the connection cannot be established
+     */
+    @Override
+    protected void connect(SocketAddress remote, int millis) throws IOException {
+        // SocketImpl connect only specifies IOException
+        if (!(remote instanceof InetSocketAddress))
+            throw new IOException("Unsupported address type");
+        InetSocketAddress isa = (InetSocketAddress) remote;
+        if (isa.isUnresolved()) {
+            throw new UnknownHostException(isa.getHostName());
+        }
+
+        InetAddress address = isa.getAddress();
+        if (address.isAnyLocalAddress())
+            address = InetAddress.getLocalHost();
+        int port = isa.getPort();
+
+        ReentrantLock connectLock = readLock;
+        try {
+            connectLock.lock();
+            try {
+                boolean connected = false;
+                FileDescriptor fd = beginConnect(address, port);
+                try {
+
+                    // configure socket to non-blocking mode when there is a timeout
+                    if (millis > 0) {
+                        configureNonBlocking(fd);
+                    }
+
+                    int n = Net.connect(fd, address, port);
+                    if (n > 0) {
+                        // connection established
+                        connected = true;
+                    } else {
+                        assert IOStatus.okayToRetry(n);
+                        if (millis > 0) {
+                            // finish connect with timeout
+                            long nanos = MILLISECONDS.toNanos(millis);
+                            connected = timedFinishConnect(fd, nanos);
+                        } else {
+                            // finish connect, no timeout
+                            boolean polled = false;
+                            while (!polled && isOpen()) {
+                                park(fd, Net.POLLOUT);
+                                polled = Net.pollConnectNow(fd);
+                            }
+                            connected = polled && isOpen();
+                        }
+                    }
+
+                    // restore socket to blocking mode
+                    if (connected && millis > 0) {
+                        configureBlocking(fd);
+                    }
+
+                } finally {
+                    endConnect(fd, connected);
+                }
+            } finally {
+                connectLock.unlock();
+            }
+        } catch (IOException ioe) {
+            close();
+            throw SocketExceptions.of(ioe, isa);
+        }
+    }
+
+    @Override
+    protected void connect(String host, int port) throws IOException {
+        connect(new InetSocketAddress(host, port), 0);
+    }
+
+    @Override
+    protected void connect(InetAddress address, int port) throws IOException {
+        connect(new InetSocketAddress(address, port), 0);
+    }
+
+    @Override
+    protected void bind(InetAddress host, int port) throws IOException {
+        synchronized (stateLock) {
+            ensureOpen();
+            if (localport != 0)
+                throw new SocketException("Already bound");
+            NetHooks.beforeTcpBind(fd, host, port);
+            Net.bind(fd, host, port);
+            // set the address field to the given host address to keep
+            // compatibility with PlainSocketImpl. When binding to 0.0.0.0
+            // then the actual local address will be ::0 when IPv6 is enabled.
+            address = host;
+            localport = Net.localAddress(fd).getPort();
+        }
+    }
+
+    @Override
+    protected void listen(int backlog) throws IOException {
+        synchronized (stateLock) {
+            ensureOpen();
+            if (localport == 0)
+                throw new SocketException("Not bound");
+            Net.listen(fd, backlog < 1 ? 50 : backlog);
+        }
+    }
+
+    /**
+     * Marks the beginning of an accept operation that might block.
+     * @throws SocketException if the socket is closed
+     */
+    private FileDescriptor beginAccept() throws SocketException {
+        synchronized (stateLock) {
+            ensureOpen();
+            if (!stream)
+                throw new SocketException("Not a stream socket");
+            if (localport == 0)
+                throw new SocketException("Not bound");
+            readerThread = NativeThread.current();
+            return fd;
+        }
+    }
+
+    /**
+     * Marks the end of an accept operation that may have blocked.
+     * @throws SocketException is the socket is closed
+     */
+    private void endAccept(boolean completed) throws SocketException {
+        synchronized (stateLock) {
+            int state = this.state;
+            readerThread = 0;
+            if (state == ST_CLOSING)
+                tryFinishClose();
+            if (!completed && state >= ST_CLOSING)
+                throw new SocketException("Socket closed");
+        }
+    }
+
+    /**
+     * Accepts a new connection with a timeout.
+     * @throws SocketTimeoutException if the accept timeout elapses
+     */
+    private int timedAccept(FileDescriptor fd,
+                            FileDescriptor newfd,
+                            InetSocketAddress[] isaa,
+                            long nanos)
+        throws IOException
+    {
+        long startNanos = System.nanoTime();
+        int n = Net.accept(fd, newfd, isaa);
+        while (n == IOStatus.UNAVAILABLE && isOpen()) {
+            long remainingNanos = nanos - (System.nanoTime() - startNanos);
+            if (remainingNanos <= 0) {
+                throw new SocketTimeoutException("Accept timed out");
+            }
+            park(fd, Net.POLLIN, remainingNanos);
+            n = Net.accept(fd, newfd, isaa);
+        }
+        return n;
+    }
+
+    /**
+     * Accepts a new connection so that the given SocketImpl is connected to
+     * the peer. The SocketImpl must be a newly created NioSocketImpl.
+     */
+    @Override
+    protected void accept(SocketImpl si) throws IOException {
+        NioSocketImpl nsi = (NioSocketImpl) si;
+        if (nsi.state != ST_NEW)
+            throw new SocketException("Not a newly created SocketImpl");
+
+        FileDescriptor newfd = new FileDescriptor();
+        InetSocketAddress[] isaa = new InetSocketAddress[1];
+
+        // acquire the lock, adjusting the timeout for cases where several
+        // threads are accepting connections and there is a timeout set
+        ReentrantLock acceptLock = readLock;
+        int timeout = this.timeout;
+        long remainingNanos = 0;
+        if (timeout > 0) {
+            remainingNanos = tryLock(acceptLock, timeout, MILLISECONDS);
+            if (remainingNanos <= 0) {
+                assert !acceptLock.isHeldByCurrentThread();
+                throw new SocketTimeoutException("Accept timed out");
+            }
+        } else {
+            acceptLock.lock();
+        }
+
+        // accept a connection
+        try {
+            int n = 0;
+            FileDescriptor fd = beginAccept();
+            try {
+                if (remainingNanos > 0) {
+                    // accept with timeout
+                    configureNonBlocking(fd);
+                    n = timedAccept(fd, newfd, isaa, remainingNanos);
+                } else {
+                    // accept, no timeout
+                    n = Net.accept(fd, newfd, isaa);
+                    while (IOStatus.okayToRetry(n) && isOpen()) {
+                        park(fd, Net.POLLIN);
+                        n = Net.accept(fd, newfd, isaa);
+                    }
+                }
+            } finally {
+                endAccept(n > 0);
+                assert IOStatus.check(n);
+            }
+        } finally {
+            acceptLock.unlock();
+        }
+
+        // get local address and configure accepted socket to blocking mode
+        InetSocketAddress localAddress;
+        try {
+            localAddress = Net.localAddress(newfd);
+            IOUtil.configureBlocking(newfd, true);
+        } catch (IOException ioe) {
+            nd.close(newfd);
+            throw ioe;
+        }
+
+        // set the fields
+        synchronized (nsi.stateLock) {
+            nsi.fd = newfd;
+            nsi.stream = true;
+            nsi.closer = FileDescriptorCloser.create(nsi);
+            nsi.localport = localAddress.getPort();
+            nsi.address = isaa[0].getAddress();
+            nsi.port = isaa[0].getPort();
+            nsi.state = ST_CONNECTED;
+        }
+    }
+
+    @Override
+    protected InputStream getInputStream() {
+        return new InputStream() {
+            @Override
+            public int read() throws IOException {
+                byte[] a = new byte[1];
+                int n = read(a, 0, 1);
+                return (n > 0) ? (a[0] & 0xff) : -1;
+            }
+            @Override
+            public int read(byte[] b, int off, int len) throws IOException {
+                return NioSocketImpl.this.read(b, off, len);
+            }
+            @Override
+            public int available() throws IOException {
+                return NioSocketImpl.this.available();
+            }
+            @Override
+            public void close() throws IOException {
+                NioSocketImpl.this.close();
+            }
+        };
+    }
+
+    @Override
+    protected OutputStream getOutputStream() {
+        return new OutputStream() {
+            @Override
+            public void write(int b) throws IOException {
+                byte[] a = new byte[]{(byte) b};
+                write(a, 0, 1);
+            }
+            @Override
+            public void write(byte[] b, int off, int len) throws IOException {
+                NioSocketImpl.this.write(b, off, len);
+            }
+            @Override
+            public void close() throws IOException {
+                NioSocketImpl.this.close();
+            }
+        };
+    }
+
+    @Override
+    protected int available() throws IOException {
+        synchronized (stateLock) {
+            ensureOpenAndConnected();
+            if (isInputClosed) {
+                return 0;
+            } else {
+                return Net.available(fd);
+            }
+        }
+    }
+
+    /**
+     * Closes the socket if there are no I/O operations in progress.
+     */
+    private boolean tryClose() throws IOException {
+        assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
+        if (readerThread == 0 && writerThread == 0) {
+            try {
+                closer.run();
+            } catch (UncheckedIOException ioe) {
+                throw ioe.getCause();
+            } finally {
+                state = ST_CLOSED;
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Invokes tryClose to attempt to close the socket.
+     *
+     * This method is used for deferred closing by I/O operations.
+     */
+    private void tryFinishClose() {
+        try {
+            tryClose();
+        } catch (IOException ignore) { }
+    }
+
+    /**
+     * Closes the socket. If there are I/O operations in progress then the
+     * socket is pre-closed and the threads are signalled. The socket will be
+     * closed when the last I/O operation aborts.
+     */
+    @Override
+    protected void close() throws IOException {
+        synchronized (stateLock) {
+            int state = this.state;
+            if (state >= ST_CLOSING)
+                return;
+            if (state == ST_NEW) {
+                // stillborn
+                this.state = ST_CLOSED;
+                return;
+            }
+            this.state = ST_CLOSING;
+
+            // shutdown output when linger interval not set to 0
+            try {
+                var SO_LINGER = StandardSocketOptions.SO_LINGER;
+                if ((int) Net.getSocketOption(fd, SO_LINGER) != 0) {
+                    Net.shutdown(fd, Net.SHUT_WR);
+                }
+            } catch (IOException ignore) { }
+
+            // attempt to close the socket. If there are I/O operations in progress
+            // then the socket is pre-closed and the thread(s) signalled. The
+            // last thread will close the file descriptor.
+            if (!tryClose()) {
+                nd.preClose(fd);
+                long reader = readerThread;
+                if (reader != 0)
+                    NativeThread.signal(reader);
+                long writer = writerThread;
+                if (writer != 0)
+                    NativeThread.signal(writer);
+            }
+        }
+    }
+
+    // the socket options supported by client and server sockets
+    private static volatile Set<SocketOption<?>> clientSocketOptions;
+    private static volatile Set<SocketOption<?>> serverSocketOptions;
+
+    @Override
+    protected Set<SocketOption<?>> supportedOptions() {
+        Set<SocketOption<?>> options = (server) ? serverSocketOptions : clientSocketOptions;
+        if (options == null) {
+            options = new HashSet<>();
+            options.add(StandardSocketOptions.SO_RCVBUF);
+            options.add(StandardSocketOptions.SO_REUSEADDR);
+            if (server) {
+                // IP_TOS added for server socket to maintain compatibility
+                options.add(StandardSocketOptions.IP_TOS);
+                options.addAll(ExtendedSocketOptions.serverSocketOptions());
+            } else {
+                options.add(StandardSocketOptions.IP_TOS);
+                options.add(StandardSocketOptions.SO_KEEPALIVE);
+                options.add(StandardSocketOptions.SO_SNDBUF);
+                options.add(StandardSocketOptions.SO_LINGER);
+                options.add(StandardSocketOptions.TCP_NODELAY);
+                options.addAll(ExtendedSocketOptions.clientSocketOptions());
+            }
+            if (Net.isReusePortAvailable())
+                options.add(StandardSocketOptions.SO_REUSEPORT);
+            options = Collections.unmodifiableSet(options);
+            if (server) {
+                serverSocketOptions = options;
+            } else {
+                clientSocketOptions = options;
+            }
+        }
+        return options;
+    }
+
+    @Override
+    protected <T> void setOption(SocketOption<T> opt, T value) throws IOException {
+        if (!supportedOptions().contains(opt))
+            throw new UnsupportedOperationException("'" + opt + "' not supported");
+        if (!opt.type().isInstance(value))
+            throw new IllegalArgumentException("Invalid value '" + value + "'");
+        synchronized (stateLock) {
+            ensureOpen();
+            if (opt == StandardSocketOptions.IP_TOS) {
+                // maps to IP_TOS or IPV6_TCLASS
+                Net.setSocketOption(fd, family(), opt, value);
+            } else if (opt == StandardSocketOptions.SO_REUSEADDR) {
+                boolean b = (boolean) value;
+                if (Net.useExclusiveBind()) {
+                    isReuseAddress = b;
+                } else {
+                    Net.setSocketOption(fd, opt, b);
+                }
+            } else {
+                // option does not need special handling
+                Net.setSocketOption(fd, opt, value);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <T> T getOption(SocketOption<T> opt) throws IOException {
+        if (!supportedOptions().contains(opt))
+            throw new UnsupportedOperationException("'" + opt + "' not supported");
+        synchronized (stateLock) {
+            ensureOpen();
+            if (opt == StandardSocketOptions.IP_TOS) {
+                return (T) Net.getSocketOption(fd, family(), opt);
+            } else if (opt == StandardSocketOptions.SO_REUSEADDR) {
+                if (Net.useExclusiveBind()) {
+                    return (T) Boolean.valueOf(isReuseAddress);
+                } else {
+                    return (T) Net.getSocketOption(fd, opt);
+                }
+            } else {
+                // option does not need special handling
+                return (T) Net.getSocketOption(fd, opt);
+            }
+        }
+    }
+
+    private boolean booleanValue(Object value, String desc) throws SocketException {
+        if (!(value instanceof Boolean))
+            throw new SocketException("Bad value for " + desc);
+        return (boolean) value;
+    }
+
+    private int intValue(Object value, String desc) throws SocketException {
+        if (!(value instanceof Integer))
+            throw new SocketException("Bad value for " + desc);
+        return (int) value;
+    }
+
+    @Override
+    public void setOption(int opt, Object value) throws SocketException {
+        synchronized (stateLock) {
+            ensureOpen();
+            try {
+                switch (opt) {
+                case SO_LINGER: {
+                    // the value is "false" to disable, or linger interval to enable
+                    int i;
+                    if (value instanceof Boolean && ((boolean) value) == false) {
+                        i = -1;
+                    } else {
+                        i = intValue(value, "SO_LINGER");
+                    }
+                    Net.setSocketOption(fd, StandardSocketOptions.SO_LINGER, i);
+                    break;
+                }
+                case SO_TIMEOUT: {
+                    int i = intValue(value, "SO_TIMEOUT");
+                    if (i < 0)
+                        throw new IllegalArgumentException("timeout < 0");
+                    timeout = i;
+                    break;
+                }
+                case IP_TOS: {
+                    int i = intValue(value, "IP_TOS");
+                    Net.setSocketOption(fd, family(), StandardSocketOptions.IP_TOS, i);
+                    break;
+                }
+                case TCP_NODELAY: {
+                    boolean b = booleanValue(value, "TCP_NODELAY");
+                    Net.setSocketOption(fd, StandardSocketOptions.TCP_NODELAY, b);
+                    break;
+                }
+                case SO_SNDBUF: {
+                    int i = intValue(value, "SO_SNDBUF");
+                    if (i <= 0)
+                        throw new SocketException("SO_SNDBUF <= 0");
+                    Net.setSocketOption(fd, StandardSocketOptions.SO_SNDBUF, i);
+                    break;
+                }
+                case SO_RCVBUF: {
+                    int i = intValue(value, "SO_RCVBUF");
+                    if (i <= 0)
+                        throw new SocketException("SO_RCVBUF <= 0");
+                    Net.setSocketOption(fd, StandardSocketOptions.SO_RCVBUF, i);
+                    break;
+                }
+                case SO_KEEPALIVE: {
+                    boolean b = booleanValue(value, "SO_KEEPALIVE");
+                    Net.setSocketOption(fd, StandardSocketOptions.SO_KEEPALIVE, b);
+                    break;
+                }
+                case SO_OOBINLINE: {
+                    boolean b = booleanValue(value, "SO_OOBINLINE");
+                    Net.setSocketOption(fd, ExtendedSocketOption.SO_OOBINLINE, b);
+                    break;
+                }
+                case SO_REUSEADDR: {
+                    boolean b = booleanValue(value, "SO_REUSEADDR");
+                    if (Net.useExclusiveBind()) {
+                        isReuseAddress = b;
+                    } else {
+                        Net.setSocketOption(fd, StandardSocketOptions.SO_REUSEADDR, b);
+                    }
+                    break;
+                }
+                case SO_REUSEPORT: {
+                    if (!Net.isReusePortAvailable())
+                        throw new SocketException("SO_REUSEPORT not supported");
+                    boolean b = booleanValue(value, "SO_REUSEPORT");
+                    Net.setSocketOption(fd, StandardSocketOptions.SO_REUSEPORT, b);
+                    break;
+                }
+                default:
+                    throw new SocketException("Unknown option " + opt);
+                }
+            } catch (SocketException e) {
+                throw e;
+            } catch (IllegalArgumentException | IOException e) {
+                throw new SocketException(e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    public Object getOption(int opt) throws SocketException {
+        synchronized (stateLock) {
+            ensureOpen();
+            try {
+                switch (opt) {
+                case SO_TIMEOUT:
+                    return timeout;
+                case TCP_NODELAY:
+                    return Net.getSocketOption(fd, StandardSocketOptions.TCP_NODELAY);
+                case SO_OOBINLINE:
+                    return Net.getSocketOption(fd, ExtendedSocketOption.SO_OOBINLINE);
+                case SO_LINGER: {
+                    // return "false" when disabled, linger interval when enabled
+                    int i = (int) Net.getSocketOption(fd, StandardSocketOptions.SO_LINGER);
+                    if (i == -1) {
+                        return Boolean.FALSE;
+                    } else {
+                        return i;
+                    }
+                }
+                case SO_REUSEADDR:
+                    if (Net.useExclusiveBind()) {
+                        return isReuseAddress;
+                    } else {
+                        return Net.getSocketOption(fd, StandardSocketOptions.SO_REUSEADDR);
+                    }
+                case SO_BINDADDR:
+                    return Net.localAddress(fd).getAddress();
+                case SO_SNDBUF:
+                    return Net.getSocketOption(fd, StandardSocketOptions.SO_SNDBUF);
+                case SO_RCVBUF:
+                    return Net.getSocketOption(fd, StandardSocketOptions.SO_RCVBUF);
+                case IP_TOS:
+                    return Net.getSocketOption(fd, family(), StandardSocketOptions.IP_TOS);
+                case SO_KEEPALIVE:
+                    return Net.getSocketOption(fd, StandardSocketOptions.SO_KEEPALIVE);
+                case SO_REUSEPORT:
+                    if (!Net.isReusePortAvailable())
+                        throw new SocketException("SO_REUSEPORT not supported");
+                    return Net.getSocketOption(fd, StandardSocketOptions.SO_REUSEPORT);
+                default:
+                    throw new SocketException("Unknown option " + opt);
+                }
+            } catch (SocketException e) {
+                throw e;
+            } catch (IllegalArgumentException | IOException e) {
+                throw new SocketException(e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    protected void shutdownInput() throws IOException {
+        synchronized (stateLock) {
+            ensureOpenAndConnected();
+            if (!isInputClosed) {
+                Net.shutdown(fd, Net.SHUT_RD);
+                isInputClosed = true;
+            }
+        }
+    }
+
+    @Override
+    protected void shutdownOutput() throws IOException {
+        synchronized (stateLock) {
+            ensureOpenAndConnected();
+            if (!isOutputClosed) {
+                Net.shutdown(fd, Net.SHUT_WR);
+                isOutputClosed = true;
+            }
+        }
+    }
+
+    @Override
+    protected boolean supportsUrgentData() {
+        return true;
+    }
+
+    @Override
+    protected void sendUrgentData(int data) throws IOException {
+        writeLock.lock();
+        try {
+            int n = 0;
+            FileDescriptor fd = beginWrite();
+            try {
+                do {
+                    n = Net.sendOOB(fd, (byte) data);
+                } while (n == IOStatus.INTERRUPTED && isOpen());
+                if (n == IOStatus.UNAVAILABLE) {
+                    throw new SocketException("No buffer space available");
+                }
+            } finally {
+                endWrite(n > 0);
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * A task that closes a SocketImpl's file descriptor. The task runs when the
+     * SocketImpl is explicitly closed and when the SocketImpl becomes phantom
+     * reachable.
+     */
+    private static class FileDescriptorCloser implements Runnable {
+        private static final VarHandle CLOSED;
+        static {
+            try {
+                MethodHandles.Lookup l = MethodHandles.lookup();
+                CLOSED = l.findVarHandle(FileDescriptorCloser.class,
+                                         "closed",
+                                         boolean.class);
+            } catch (Exception e) {
+                throw new InternalError(e);
+            }
+        }
+
+        private final FileDescriptor fd;
+        private final boolean stream;
+        private volatile boolean closed;
+
+        FileDescriptorCloser(FileDescriptor fd, boolean stream) {
+            this.fd = fd;
+            this.stream = stream;
+        }
+
+        static FileDescriptorCloser create(NioSocketImpl impl) {
+            assert Thread.holdsLock(impl.stateLock);
+            var closer = new FileDescriptorCloser(impl.fd, impl.stream);
+            CleanerFactory.cleaner().register(impl, closer);
+            return closer;
+        }
+
+        @Override
+        public void run() {
+            if (CLOSED.compareAndSet(this, false, true)) {
+                try {
+                    nd.close(fd);
+                } catch (IOException ioe) {
+                    throw new UncheckedIOException(ioe);
+                } finally {
+                    if (!stream) {
+                        // decrement
+                        ResourceManager.afterUdpClose();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Attempts to acquire the given lock within the given waiting time.
+     * @return the remaining time in nanoseconds when the lock is acquired, zero
+     *         or less if the lock was not acquired before the timeout expired
+     */
+    private static long tryLock(ReentrantLock lock, long timeout, TimeUnit unit) {
+        assert timeout > 0;
+        boolean interrupted = false;
+        long nanos = NANOSECONDS.convert(timeout, unit);
+        long remainingNanos = nanos;
+        long startNanos = System.nanoTime();
+        boolean acquired = false;
+        while (!acquired && (remainingNanos > 0)) {
+            try {
+                acquired = lock.tryLock(remainingNanos, NANOSECONDS);
+            } catch (InterruptedException e) {
+                interrupted = true;
+            }
+            remainingNanos = nanos - (System.nanoTime() - startNanos);
+        }
+        if (acquired && remainingNanos <= 0L)
+            lock.unlock();  // release lock if timeout has expired
+        if (interrupted)
+            Thread.currentThread().interrupt();
+        return remainingNanos;
+    }
+
+    /**
+     * Returns the socket protocol family.
+     */
+    private static ProtocolFamily family() {
+        if (Net.isIPv6Available()) {
+            return StandardProtocolFamily.INET6;
+        } else {
+            return StandardProtocolFamily.INET;
+        }
+    }
+}
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -147,6 +147,9 @@
         Objects.requireNonNull(name);
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
+        if (!name.type().isInstance(value))
+            throw new IllegalArgumentException("Invalid value '" + value + "'");
+
         synchronized (stateLock) {
             ensureOpen();
 
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -218,6 +218,8 @@
         Objects.requireNonNull(name);
         if (!supportedOptions().contains(name))
             throw new UnsupportedOperationException("'" + name + "' not supported");
+        if (!name.type().isInstance(value))
+            throw new IllegalArgumentException("Invalid value '" + value + "'");
 
         synchronized (stateLock) {
             ensureOpen();
--- a/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -393,29 +393,22 @@
             return (TypeVariable)getType();
         }
 
-        // For toString, the declaration of a type variable should
-        // including information about its bounds, etc. However, the
+        // The declaration of a type variable should
+        // include information about its bounds, etc. However, the
         // use of a type variable should not. For that reason, it is
-        // acceptable for the toString implementation of
+        // acceptable for the toString and hashCode implementations of
         // AnnotatedTypeVariableImpl to use the inherited
-        // implementation from AnnotatedTypeBaseImpl.
+        // implementations from AnnotatedTypeBaseImpl.
 
         @Override
         public boolean equals(Object o) {
             if (o instanceof AnnotatedTypeVariable) {
                 AnnotatedTypeVariable that = (AnnotatedTypeVariable) o;
-                return equalsTypeAndAnnotations(that) &&
-                    Arrays.equals(getAnnotatedBounds(), that.getAnnotatedBounds());
+                return equalsTypeAndAnnotations(that);
             } else {
                 return false;
             }
         }
-
-        @Override
-        public int hashCode() {
-            return baseHashCode() ^
-                Objects.hash((Object[])getAnnotatedBounds());
-        }
     }
 
     private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl
--- a/src/java.base/share/classes/sun/security/ssl/SSLCipher.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/SSLCipher.java	Thu May 30 19:49:55 2019 +0200
@@ -31,6 +31,7 @@
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.Key;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivilegedAction;
 import java.security.SecureRandom;
 import java.security.Security;
@@ -42,6 +43,7 @@
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
 import javax.crypto.SecretKey;
 import javax.crypto.ShortBufferException;
 import javax.crypto.spec.GCMParameterSpec;
@@ -491,16 +493,31 @@
 
         // availability of this bulk cipher
         //
-        // We assume all supported ciphers are always available since they are
-        // shipped with the SunJCE  provider.  However, AES/256 is unavailable
-        // when the default JCE policy jurisdiction files are installed because
-        // of key length restrictions.
-        this.isAvailable = allowed && isUnlimited(keySize, transformation);
+        // AES/256 is unavailable when the default JCE policy jurisdiction files
+        // are installed because of key length restrictions.
+        this.isAvailable = allowed && isUnlimited(keySize, transformation) &&
+                isTransformationAvailable(transformation);
 
         this.readCipherGenerators = readCipherGenerators;
         this.writeCipherGenerators = writeCipherGenerators;
     }
 
+    private static boolean isTransformationAvailable(String transformation) {
+        if (transformation.equals("NULL")) {
+            return true;
+        }
+        try {
+            Cipher.getInstance(transformation);
+            return true;
+        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+            if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
+                SSLLogger.fine("Transformation " + transformation + " is" +
+                        " not available.");
+            }
+        }
+        return false;
+    }
+
     SSLReadCipher createReadCipher(Authenticator authenticator,
             ProtocolVersion protocolVersion,
             SecretKey key, IvParameterSpec iv,
--- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -379,7 +379,8 @@
 
                 boolean isSupported = false;
                 for (ProtocolVersion protocol : protocols) {
-                    if (!suite.supports(protocol)) {
+                    if (!suite.supports(protocol) ||
+                            !suite.bulkCipher.isAvailable()) {
                         continue;
                     }
 
--- a/src/java.base/share/conf/security/java.security	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/conf/security/java.security	Thu May 30 19:49:55 2019 +0200
@@ -1022,27 +1022,6 @@
 #    java.rmi.dgc.Lease;\
 #    maxdepth=5;maxarray=10000
 
-# CORBA ORBIorTypeCheckRegistryFilter
-# Type check enhancement for ORB::string_to_object processing
-#
-# An IOR type check filter, if configured, is used by an ORB during
-# an ORB::string_to_object invocation to check the veracity of the type encoded
-# in the ior string.
-#
-# The filter pattern consists of a semi-colon separated list of class names.
-# The configured list contains the binary class names of the IDL interface types
-# corresponding to the IDL stub class to be instantiated.
-# As such, a filter specifies a list of IDL stub classes that will be
-# allowed by an ORB when an ORB::string_to_object is invoked.
-# It is used to specify a white list configuration of acceptable
-# IDL stub types which may be contained in a stringified IOR
-# parameter passed as input to an ORB::string_to_object method.
-#
-# Note: This property is currently used by the JDK Reference implementation.
-# It is not guaranteed to be examined and used by other implementations.
-#
-#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
-
 #
 # JCEKS Encrypted Key Serial Filter
 #
--- a/src/java.base/share/man/java.1	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/man/java.1	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 '\" t
-.\" Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
+.\" Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
 .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 .\"
 .\" This code is free software; you can redistribute it and/or modify it
@@ -1162,6 +1162,8 @@
 none
 .RS 4
 Do not verify the bytecode\&. This reduces startup time and also reduces the protection provided by Java\&.
+.sp
+This option is deprecated and may be removed in a future release.
 .RE
 .PP
 remote
--- a/src/java.base/share/native/libjli/java.c	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/share/native/libjli/java.c	Thu May 30 19:49:55 2019 +0200
@@ -1437,6 +1437,10 @@
         } else if (JLI_StrCmp(arg, "-verifyremote") == 0) {
             AddOption("-Xverify:remote", NULL);
         } else if (JLI_StrCmp(arg, "-noverify") == 0) {
+            /*
+             * Note that no 'deprecated' message is needed here because the VM
+             * issues 'deprecated' messages for -noverify and -Xverify:none.
+             */
             AddOption("-Xverify:none", NULL);
         } else if (JLI_StrCCmp(arg, "-ss") == 0 ||
                    JLI_StrCCmp(arg, "-oss") == 0 ||
--- a/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -41,46 +41,6 @@
         init();
     }
 
-    static final ExtendedSocketOptions extendedOptions =
-            ExtendedSocketOptions.getInstance();
-
-    protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
-        if (isClosed()) {
-            throw new SocketException("Socket closed");
-        }
-        if (supportedOptions().contains(name)) {
-            if (extendedOptions.isOptionSupported(name)) {
-                extendedOptions.setOption(fd, name, value);
-            } else {
-                super.setOption(name, value);
-            }
-        } else {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    protected <T> T getOption(SocketOption<T> name) throws IOException {
-        if (isClosed()) {
-            throw new SocketException("Socket closed");
-        }
-        if (supportedOptions().contains(name)) {
-            if (extendedOptions.isOptionSupported(name)) {
-                return (T) extendedOptions.getOption(fd, name);
-            } else {
-                return super.getOption(name);
-            }
-        } else {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-    }
-
-    protected Set<SocketOption<?>> supportedOptions() {
-        HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
-        options.addAll(ExtendedSocketOptions.datagramSocketOptions());
-        return options;
-    }
-
     protected void socketSetOption(int opt, Object val) throws SocketException {
         if (opt == SocketOptions.SO_REUSEPORT &&
             !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
--- a/src/java.base/unix/classes/java/net/PlainSocketImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.base/unix/classes/java/net/PlainSocketImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -25,7 +25,6 @@
 package java.net;
 
 import java.io.IOException;
-import java.io.FileDescriptor;
 import java.util.Set;
 import java.util.HashSet;
 import sun.net.ext.ExtendedSocketOptions;
@@ -49,50 +48,6 @@
         super(isServer);
     }
 
-    static final ExtendedSocketOptions extendedOptions =
-            ExtendedSocketOptions.getInstance();
-
-    protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
-        if (isClosedOrPending()) {
-            throw new SocketException("Socket closed");
-        }
-        if (supportedOptions().contains(name)) {
-            if (extendedOptions.isOptionSupported(name)) {
-                extendedOptions.setOption(fd, name, value);
-            } else {
-                super.setOption(name, value);
-            }
-        } else {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    protected <T> T getOption(SocketOption<T> name) throws IOException {
-        if (isClosedOrPending()) {
-            throw new SocketException("Socket closed");
-        }
-        if (supportedOptions().contains(name)) {
-            if (extendedOptions.isOptionSupported(name)) {
-                return (T) extendedOptions.getOption(fd, name);
-            } else {
-                return super.getOption(name);
-            }
-        } else {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-    }
-
-    protected Set<SocketOption<?>> supportedOptions() {
-        HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
-        if (isServer) {
-            options.addAll(ExtendedSocketOptions.serverSocketOptions());
-        } else {
-            options.addAll(ExtendedSocketOptions.clientSocketOptions());
-        }
-        return options;
-    }
-
     protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
         if (opt == SocketOptions.SO_REUSEPORT &&
             !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
--- a/src/java.management/share/classes/java/lang/management/ManagementFactory.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.management/share/classes/java/lang/management/ManagementFactory.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -872,12 +872,13 @@
     public static Set<Class<? extends PlatformManagedObject>>
            getPlatformManagementInterfaces()
     {
-        return platformComponents()
+        // local variable required here; see JDK-8223553
+        Stream<Class<? extends PlatformManagedObject>> pmos = platformComponents()
                 .stream()
                 .flatMap(pc -> pc.mbeanInterfaces().stream())
                 .filter(clazz -> PlatformManagedObject.class.isAssignableFrom(clazz))
-                .map(clazz -> clazz.asSubclass(PlatformManagedObject.class))
-                .collect(Collectors.toSet());
+                .map(clazz -> clazz.asSubclass(PlatformManagedObject.class));
+        return pmos.collect(Collectors.toSet());
     }
 
     private static final String NOTIF_EMITTER =
--- a/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * 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,8 +62,6 @@
 
     private static final Debug debug = Debug.getInstance("certpath");
 
-    private final static boolean DEBUG = false;
-
     /**
      * LDAP attribute identifiers.
      */
@@ -72,7 +70,6 @@
     private static final String CROSS_CERT = "crossCertificatePair;binary";
     private static final String CRL = "certificateRevocationList;binary";
     private static final String ARL = "authorityRevocationList;binary";
-    private static final String DELTA_CRL = "deltaRevocationList;binary";
 
     // Constants for various empty values
     private final static String[] STRING0 = new String[0];
@@ -113,6 +110,7 @@
      * their binary stored form.
      */
     private CertificateFactory cf;
+
     /**
      * The JNDI directory context.
      */
@@ -241,10 +239,6 @@
             return name;
         }
 
-        String getName() {
-            return name;
-        }
-
         void addRequestedAttribute(String attrId) {
             if (valueMap != null) {
                 throw new IllegalStateException("Request already sent");
@@ -260,9 +254,9 @@
          * @throws NamingException      if a naming exception occurs
          */
         byte[][] getValues(String attrId) throws NamingException {
-            if (DEBUG && ((cacheHits + cacheMisses) % 50 == 0)) {
-                System.out.println("Cache hits: " + cacheHits + "; misses: "
-                        + cacheMisses);
+            if (debug != null && Debug.isVerbose() && ((cacheHits + cacheMisses) % 50 == 0)) {
+                debug.println("LDAPRequest Cache hits: " + cacheHits +
+                    "; misses: " + cacheMisses);
             }
             String cacheKey = name + "|" + attrId;
             byte[][] values = valueCache.get(cacheKey);
@@ -294,11 +288,11 @@
             if (valueMap != null) {
                 return valueMap;
             }
-            if (DEBUG) {
-                System.out.println("Request: " + name + ":" + requestedAttributes);
+            if (debug != null && Debug.isVerbose()) {
+                debug.println("LDAPRequest: " + name + ":" + requestedAttributes);
                 requests++;
                 if (requests % 5 == 0) {
-                    System.out.println("LDAP requests: " + requests);
+                    debug.println("LDAP requests: " + requests);
                 }
             }
             valueMap = new HashMap<>(8);
--- a/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -26,14 +26,15 @@
 package jdk.internal.net.http;
 
 import java.io.IOException;
+import java.net.http.HttpClient;
+import java.net.http.HttpResponse;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
-import java.util.function.Function;
-import java.net.http.HttpClient;
-import java.net.http.HttpResponse;
+
 import jdk.internal.net.http.common.Logger;
 import jdk.internal.net.http.common.MinimalFuture;
 import jdk.internal.net.http.common.Utils;
+
 import static java.net.http.HttpClient.Version.HTTP_1_1;
 
 /**
@@ -92,8 +93,10 @@
             CompletableFuture<Http2Connection> c2f = c2.getConnectionFor(request, exchange);
             if (debug.on())
                 debug.log("get: Trying to get HTTP/2 connection");
-            return c2f.handle((h2c, t) -> createExchangeImpl(h2c, t, exchange, connection))
-                    .thenCompose(Function.identity());
+            // local variable required here; see JDK-8223553
+            CompletableFuture<CompletableFuture<? extends ExchangeImpl<U>>> fxi =
+                c2f.handle((h2c, t) -> createExchangeImpl(h2c, t, exchange, connection));
+            return fxi.thenCompose(x->x);
         }
     }
 
--- a/src/java.security.sasl/share/classes/com/sun/security/sasl/digest/DigestMD5Server.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.security.sasl/share/classes/com/sun/security/sasl/digest/DigestMD5Server.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -195,8 +195,13 @@
         switch (step) {
         case 1:
             if (response.length != 0) {
-                throw new SaslException(
-                    "DIGEST-MD5 must not have an initial response");
+                // We do not support "subsequent authentication" (client
+                // initial response). According to
+                // https://tools.ietf.org/html/rfc2831#section-2.2
+                // If the server does not support subsequent authentication,
+                // then it sends a "digest-challenge", and authentication
+                // proceeds as in initial authentication.
+                logger.log(Level.FINE, "Ignoring initial response");
             }
 
             /* Generate first challenge */
--- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/CanonicalizationMethod.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/CanonicalizationMethod.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -90,6 +90,24 @@
         "http://www.w3.org/2001/10/xml-exc-c14n#WithComments";
 
     /**
+     * The <a href="https://www.w3.org/TR/xml-c14n11/">Canonical XML 1.1
+     * (without comments)</a> canonicalization method algorithm URI.
+     *
+     * @since 13
+     */
+    final static String INCLUSIVE_11 = "http://www.w3.org/2006/12/xml-c14n11";
+
+    /**
+     * The <a href="https://www.w3.org/TR/xml-c14n11/#WithComments">
+     * Canonical XML 1.1 with comments</a> canonicalization method algorithm
+     * URI.
+     *
+     * @since 13
+     */
+    final static String INCLUSIVE_11_WITH_COMMENTS =
+        "http://www.w3.org/2006/12/xml-c14n11#WithComments";
+
+    /**
      * Returns the algorithm-specific input parameters associated with this
      * <code>CanonicalizationMethod</code>.
      *
--- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/TransformService.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/TransformService.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * 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,9 +141,18 @@
      * may be different than the order of providers returned by
      * {@link Security#getProviders() Security.getProviders()}.
      *
-     * @param algorithm the URI of the algorithm
+     * @param algorithm the URI of the algorithm. See the
+     *    {@code TransformService} section in the
+     *    <a href=
+     *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-transform-transformservice-algorithms">
+     *    Java Security Standard Algorithm Names Specification</a> for a list of
+     *    standard transform algorithms.
      * @param mechanismType the type of the XML processing mechanism and
-     *   representation
+     *    representation. See the {@code TransformService} section in the
+     *    <a href=
+     *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-xmlsignaturefactorykeyinfofactorytransformservice-mechanisms">
+     *    Java Security Standard Algorithm Names Specification</a> for a list of
+     *    standard mechanism types.
      * @return a new <code>TransformService</code>
      * @throws NullPointerException if <code>algorithm</code> or
      *   <code>mechanismType</code> is  <code>null</code>
@@ -193,9 +202,18 @@
      * <code>Provider</code> object does not have to be registered in the
      * provider list.
      *
-     * @param algorithm the URI of the algorithm
+     * @param algorithm the URI of the algorithm. See the
+     *    {@code TransformService} section in the
+     *    <a href=
+     *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-transform-transformservice-algorithms">
+     *    Java Security Standard Algorithm Names Specification</a> for a list of
+     *    standard transform algorithms.
      * @param mechanismType the type of the XML processing mechanism and
-     *   representation
+     *    representation. See the {@code TransformService} section in the
+     *    <a href=
+     *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-xmlsignaturefactorykeyinfofactorytransformservice-mechanisms">
+     *    Java Security Standard Algorithm Names Specification</a> for a list of
+     *    standard mechanism types.
      * @param provider the <code>Provider</code> object
      * @return a new <code>TransformService</code>
      * @throws NullPointerException if <code>provider</code>,
@@ -246,9 +264,18 @@
      * <p>Note that the list of registered providers may be retrieved via
      * the {@link Security#getProviders() Security.getProviders()} method.
      *
-     * @param algorithm the URI of the algorithm
+     * @param algorithm the URI of the algorithm. See the
+     *    {@code TransformService} section in the
+     *    <a href=
+     *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-transform-transformservice-algorithms">
+     *    Java Security Standard Algorithm Names Specification</a> for a list of
+     *    standard transform algorithms.
      * @param mechanismType the type of the XML processing mechanism and
-     *   representation
+     *    representation. See the {@code TransformService} section in the
+     *    <a href=
+     *    "{@docRoot}/../specs/security/standard-names.html#xml-signature-xmlsignaturefactorykeyinfofactorytransformservice-mechanisms">
+     *    Java Security Standard Algorithm Names Specification</a> for a list of
+     *    standard mechanism types.
      * @param provider the string name of the provider
      * @return a new <code>TransformService</code>
      * @throws NoSuchProviderException if the specified provider is not
--- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/keyinfo/KeyValue.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/keyinfo/KeyValue.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 package javax.xml.crypto.dsig.keyinfo;
 
 import java.security.KeyException;
-import java.security.KeyStore;
 import java.security.PublicKey;
 import java.security.interfaces.DSAPublicKey;
 import java.security.interfaces.RSAPublicKey;
@@ -47,6 +46,8 @@
  *      &lt;choice&gt;
  *        &lt;element ref="ds:DSAKeyValue"/&gt;
  *        &lt;element ref="ds:RSAKeyValue"/&gt;
+ *        &lt;!-- &lt;element ref="dsig11:ECKeyValue"/&gt; --&gt;
+ *        &lt;!-- ECC keys (XMLDsig 1.1) will use the any element --&gt;
  *        &lt;any namespace="##other" processContents="lax"/&gt;
  *      &lt;/choice&gt;
  *    &lt;/complexType&gt;
@@ -75,8 +76,30 @@
  *        &lt;element name="Exponent" type="ds:CryptoBinary"/&gt;
  *      &lt;/sequence&gt;
  *    &lt;/complexType&gt;
+ *
+ *    &lt;complexType name="ECKeyValueType"&gt;
+ *      &lt;sequence&gt;
+ *        &lt;choice&gt;
+ *          &lt;element name="ECParameters" type="dsig11:ECParametersType" /&gt;
+ *          &lt;element name="NamedCurve" type="dsig11:NamedCurveType" /&gt;
+ *        &lt;/choice&gt;
+ *        &lt;element name="PublicKey" type="dsig11:ECPointType" /&gt;
+ *      &lt;/sequence&gt;
+ *      &lt;attribute name="Id" type="ID" use="optional" /&gt;
+ *    &lt;/complexType&gt;
+ *
+ *    &lt;complexType name="NamedCurveType"&gt;
+ *      &lt;attribute name="URI" type="anyURI" use="required" /&gt;
+ *    &lt;/complexType&gt;
+ *
+ *    &lt;simpleType name="ECPointType"&gt;
+ *      &lt;restriction base="ds:CryptoBinary" /&gt;
+ *    &lt;/simpleType&gt;
  * </pre>
- * A <code>KeyValue</code> instance may be created by invoking the
+ * See section 4.5.2.3.1 of the W3C Recommendation for the definition
+ * of ECParametersType.
+ *
+ * <p>A <code>KeyValue</code> instance may be created by invoking the
  * {@link KeyInfoFactory#newKeyValue newKeyValue} method of the
  * {@link KeyInfoFactory} class, and passing it a {@link
  * java.security.PublicKey} representing the value of the public key. Here is
@@ -124,6 +147,16 @@
         "http://www.w3.org/2000/09/xmldsig#RSAKeyValue";
 
     /**
+     * URI identifying the EC KeyValue KeyInfo type:
+     * http://www.w3.org/2009/xmldsig11#ECKeyValue. This can be specified as
+     * the value of the <code>type</code> parameter of the
+     * {@link RetrievalMethod} class to describe a remote
+     * <code>ECKeyValue</code> structure.
+     */
+    final static String EC_TYPE =
+        "http://www.w3.org/2009/xmldsig11#ECKeyValue";
+
+    /**
      * Returns the public key of this <code>KeyValue</code>.
      *
      * @return the public key of this <code>KeyValue</code>
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -42,7 +42,7 @@
  * @xerces.internal
  *
  * @since  PR-DOM-Level-1-19980818.
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
  */
 public class DeferredDocumentImpl
     extends DocumentImpl
@@ -69,7 +69,7 @@
     // protected
 
     /** Chunk shift. */
-    protected static final int CHUNK_SHIFT = 11;           // 2^11 = 2k
+    protected static final int CHUNK_SHIFT = 8;           // 2^8 = 256
 
     /** Chunk size. */
     protected static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
@@ -78,7 +78,7 @@
     protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
 
     /** Initial chunk size. */
-    protected static final int INITIAL_CHUNK_COUNT = (1 << (16 - CHUNK_SHIFT));   // 2^16 = 64k
+    protected static final int INITIAL_CHUNK_COUNT = (1 << (13 - CHUNK_SHIFT));   // 32
 
     //
     // Data
--- a/src/java.xml/share/legal/xerces.md	Thu May 23 22:12:31 2019 +0200
+++ b/src/java.xml/share/legal/xerces.md	Thu May 30 19:49:55 2019 +0200
@@ -1,14 +1,14 @@
-## Apache Xerces v2.11.0
+## Apache Xerces v2.12.0
 
 ### Apache Xerces Notice
 <pre>
     =========================================================================
-    == NOTICE file corresponding to section 4(d) of the Apache License, ==
-    == Version 2.0, in this case for the Apache Xerces Java distribution. ==
+    == NOTICE file corresponding to section 4(d) of the Apache License,    ==
+    == Version 2.0, in this case for the Apache Xerces Java distribution.  ==
     =========================================================================
     
     Apache Xerces Java
-    Copyright 1999-2010 The Apache Software Foundation
+    Copyright 1999-2018 The Apache Software Foundation
     This product includes software developed at
     The Apache Software Foundation (http://www.apache.org/).
     Portions of this software were originally based on the following:
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,7 @@
 import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin;
 import org.graalvm.compiler.java.GraphBuilderPhase;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.PhaseSuite;
@@ -194,7 +195,16 @@
             AOTDynamicTypeStore dynoStore = new AOTDynamicTypeStore();
             AOTCompiledClass.setDynamicTypeStore(dynoStore);
 
-            AOTBackend aotBackend = new AOTBackend(this, graalOptions, backend, new HotSpotInvokeDynamicPlugin(dynoStore));
+            // AOTBackend aotBackend = new AOTBackend(this, graalOptions, backend, new HotSpotInvokeDynamicPlugin(dynoStore));
+            // Temporary workaround until JDK-8223533 is fixed.
+            // Disable invokedynamic support.
+            var indyPlugin = new HotSpotInvokeDynamicPlugin(dynoStore) {
+                @Override
+                public boolean supportsDynamicInvoke(GraphBuilderContext builder, int index, int opcode) {
+                    return false;
+                }
+            };
+            AOTBackend aotBackend = new AOTBackend(this, graalOptions, backend, indyPlugin);
             SnippetReflectionProvider snippetReflection = aotBackend.getProviders().getSnippetReflection();
             AOTCompiler compiler = new AOTCompiler(this, graalOptions, aotBackend, options.threads);
             classes = compiler.compileClasses(classes);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Thu May 30 19:49:55 2019 +0200
@@ -355,7 +355,7 @@
     private void setCompilationUnitModules(List<JCCompilationUnit> trees, Set<ModuleSymbol> rootModules, ClassSymbol c) {
         // update the module for each compilation unit
         if (multiModuleMode) {
-            checkNoAllModulePath();
+            boolean patchesAutomaticModules = false;
             for (JCCompilationUnit tree: trees) {
                 if (tree.defs.isEmpty()) {
                     tree.modle = syms.unnamedModule;
@@ -375,6 +375,7 @@
                         ModuleSymbol msym = moduleFinder.findModule(name);
                         tree.modle = msym;
                         rootModules.add(msym);
+                        patchesAutomaticModules |= (msym.flags_field & Flags.AUTOMATIC_MODULE) != 0;
 
                         if (msplocn != null) {
                             Name mspname = names.fromString(fileManager.inferModuleName(msplocn));
@@ -438,6 +439,9 @@
                     log.useSource(prev);
                 }
             }
+            if (!patchesAutomaticModules) {
+                checkNoAllModulePath();
+            }
             if (syms.unnamedModule.sourceLocation == null) {
                 syms.unnamedModule.completer = getUnnamedModuleCompleter();
                 syms.unnamedModule.sourceLocation = StandardLocation.SOURCE_PATH;
@@ -458,9 +462,11 @@
                         }
                         if (defaultModule == syms.unnamedModule) {
                             if (moduleOverride != null) {
-                                checkNoAllModulePath();
                                 defaultModule = moduleFinder.findModule(names.fromString(moduleOverride));
                                 defaultModule.patchOutputLocation = StandardLocation.CLASS_OUTPUT;
+                                if ((defaultModule.flags_field & Flags.AUTOMATIC_MODULE) == 0) {
+                                    checkNoAllModulePath();
+                                }
                             } else {
                                 // Question: why not do findAllModules and initVisiblePackages here?
                                 // i.e. body of unnamedModuleCompleter
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu May 30 19:49:55 2019 +0200
@@ -686,11 +686,12 @@
     static class ProcessorState {
         public Processor processor;
         public boolean   contributed;
-        private ArrayList<Pattern> supportedAnnotationPatterns;
-        private ArrayList<String>  supportedOptionNames;
+        private Set<String> supportedAnnotationStrings; // Used for warning generation
+        private Set<Pattern> supportedAnnotationPatterns;
+        private Set<String> supportedOptionNames;
 
         ProcessorState(Processor p, Log log, Source source, DeferredCompletionFailureHandler dcfh,
-                       boolean allowModules, ProcessingEnvironment env) {
+                       boolean allowModules, ProcessingEnvironment env, boolean lint) {
             processor = p;
             contributed = false;
 
@@ -700,18 +701,46 @@
 
                 checkSourceVersionCompatibility(source, log);
 
-                supportedAnnotationPatterns = new ArrayList<>();
-                for (String importString : processor.getSupportedAnnotationTypes()) {
-                    supportedAnnotationPatterns.add(importStringToPattern(allowModules,
-                                                                          importString,
-                                                                          processor,
-                                                                          log));
+
+                // Check for direct duplicates in the strings of
+                // supported annotation types. Do not check for
+                // duplicates that would result after stripping of
+                // module prefixes.
+                supportedAnnotationStrings = new LinkedHashSet<>();
+                supportedAnnotationPatterns = new LinkedHashSet<>();
+                for (String annotationPattern : processor.getSupportedAnnotationTypes()) {
+                    boolean patternAdded = supportedAnnotationStrings.add(annotationPattern);
+
+                    supportedAnnotationPatterns.
+                        add(importStringToPattern(allowModules, annotationPattern,
+                                                  processor, log, lint));
+                    if (lint && !patternAdded) {
+                        log.warning(Warnings.ProcDuplicateSupportedAnnotation(annotationPattern,
+                                                                              p.getClass().getName()));
+                    }
                 }
 
-                supportedOptionNames = new ArrayList<>();
+                // If a processor supports "*", that matches
+                // everything and other entries are redundant. With
+                // more work, it could be checked that the supported
+                // annotation types were otherwise non-overlapping
+                // with each other in other cases, for example "foo.*"
+                // and "foo.bar.*".
+                if (lint &&
+                    supportedAnnotationPatterns.contains(MatchingUtils.validImportStringToPattern("*")) &&
+                    supportedAnnotationPatterns.size() > 1) {
+                    log.warning(Warnings.ProcRedundantTypesWithWildcard(p.getClass().getName()));
+                }
+
+                supportedOptionNames = new LinkedHashSet<>();
                 for (String optionName : processor.getSupportedOptions() ) {
-                    if (checkOptionName(optionName, log))
-                        supportedOptionNames.add(optionName);
+                    if (checkOptionName(optionName, log)) {
+                        boolean optionAdded = supportedOptionNames.add(optionName);
+                        if (lint && !optionAdded) {
+                            log.warning(Warnings.ProcDuplicateOptionName(optionName,
+                                                                         p.getClass().getName()));
+                        }
+                    }
                 }
 
             } catch (ClientCodeException e) {
@@ -797,7 +826,8 @@
                     ProcessorState ps = new ProcessorState(psi.processorIterator.next(),
                                                            log, source, dcfh,
                                                            Feature.MODULES.allowedInSource(source),
-                                                           JavacProcessingEnvironment.this);
+                                                           JavacProcessingEnvironment.this,
+                                                           lint);
                     psi.procStateList.add(ps);
                     return ps;
                 } else
@@ -1705,7 +1735,7 @@
      * regex matching that string.  If the string is not a valid
      * import-style string, return a regex that won't match anything.
      */
-    private static Pattern importStringToPattern(boolean allowModules, String s, Processor p, Log log) {
+    private static Pattern importStringToPattern(boolean allowModules, String s, Processor p, Log log, boolean lint) {
         String module;
         String pkg;
         int slash = s.indexOf('/');
@@ -1716,15 +1746,26 @@
             module = allowModules ? ".*/" : "";
             pkg = s;
         } else {
-            module = Pattern.quote(s.substring(0, slash + 1));
+            String moduleName = s.substring(0, slash);
+            if (!SourceVersion.isIdentifier(moduleName)) {
+                return warnAndNoMatches(s, p, log, lint);
+            }
+            module = Pattern.quote(moduleName + "/");
+            // And warn if module is specified if modules aren't supported, conditional on -Xlint:proc?
             pkg = s.substring(slash + 1);
         }
         if (MatchingUtils.isValidImportString(pkg)) {
             return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg));
         } else {
+            return warnAndNoMatches(s, p, log, lint);
+        }
+    }
+
+    private static Pattern warnAndNoMatches(String s, Processor p, Log log, boolean lint) {
+        if (lint) {
             log.warning(Warnings.ProcMalformedSupportedString(s, p.getClass().getName()));
-            return noMatches; // won't match any valid identifier
         }
+        return noMatches; // won't match any valid identifier
     }
 
     /**
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu May 23 22:12:31 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu May 30 19:49:55 2019 +0200
@@ -1913,6 +1913,18 @@
 compiler.warn.proc.processor.incompatible.source.version=\
     Supported source version ''{0}'' from annotation processor ''{1}'' less than -source ''{2}''
 
+# 0: string, 1: string
+compiler.warn.proc.duplicate.option.name=\
+    Duplicate supported option ''{0}'' returned by annotation processor ''{1}''
+
+# 0: string, 1: string
+compiler.warn.proc.duplicate.supported.annotation=\
+    Duplicate supported annotation type ''{0}'' returned by annotation processor ''{1}''
+
+# 0: string
+compiler.warn.proc.redundant.types.with.wildcard=\
+    Annotation processor ''{0}'' redundantly supports both ''*'' and other annotation types
+
 compiler.warn.proc.proc-only.requested.no.procs=\
     Annotation processing without compilation requested but no processors were found.
 
@@ -3291,7 +3303,8 @@
     module name in {0} option not found: {1}
 
 compiler.err.addmods.all.module.path.invalid=\
-    --add-modules ALL-MODULE-PATH can only be used when compiling the unnamed module
+    --add-modules ALL-MODULE-PATH can only be used when compiling the unnamed module or \
+    when compiling in the context of an automatic module
 
 # 0: symbol
 compiler.err.add.exports.with.release=\
--- a/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.c	Thu May 23 22:12:31 2019 +0200
+++ b/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.c	Thu May 30 19:49:55 2019 +0200
@@ -38,7 +38,11 @@
 #define amd64 1
 #endif
 
-#ifdef i386
+#if defined(i386) && !defined(i586)
+#define i586 1
+#endif
+
+#ifdef i586
 #include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
 #endif
 
@@ -386,7 +390,7 @@
   return (err == PS_OK)? array : 0;
 }
 
-#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) || defined(ppc64le) || defined(aarch64)
+#if defined(i586) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) || defined(ppc64le) || defined(aarch64)
 JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
   (JNIEnv *env, jobject this_obj, jint lwp_id) {
 
@@ -402,7 +406,7 @@
   }
 
 #undef NPRGREG
-#ifdef i386
+#ifdef i586
 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
 #endif
 #ifdef amd64
@@ -425,7 +429,7 @@
 
 #undef REG_INDEX
 
-#ifdef i386
+#ifdef i586
 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg
 
   regs[REG_INDEX(GS)]  = (uintptr_t) gregs.xgs;
@@ -444,7 +448,7 @@
   regs[REG_INDEX(CS)]  = (uintptr_t) gregs.xcs;
   regs[REG_INDEX(SS)]  = (uintptr_t) gregs.xss;
 
-#endif /* i386 */
+#endif /* i586 */
 
 #ifdef amd64
 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
--- a/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c	Thu May 23 22:12:31 2019 +0200
+++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c	Thu May 30 19:49:55 2019 +0200
@@ -961,7 +961,7 @@
 
    if (is_debug()) {
       print_debug("integer regset\n");
-#ifdef i386
+#if defined(i586) || defined(i386)
       // print the regset
       print_debug("\teax = 0x%x\n", newthr->regs.r_eax);
       print_debug("\tebx = 0x%x\n", newthr->regs.r_ebx);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java	Thu May 30 19:49:55 2019 +0200
@@ -45,30 +45,38 @@
         return false;
     }
 
-    private static boolean commonHelp() {
+    private static boolean commonHelp(String mode) {
         // --pid <pid>
         // --exe <exe>
         // --core <core>
-        System.out.println("    --exe\t<executable image name>");
-        System.out.println("    --core\t<path to coredump>");
-        System.out.println("    --pid\t<pid of process to attach>");
+        System.out.println("    --pid <pid>      \tTo attach to and operate on the given live process.");
+        System.out.println("    --core <corefile>\tTo operate on the given core file.");
+        System.out.println("    --exe <executable for corefile>");
+        System.out.println();
+        System.out.println("    The --core and --exe options must be set together to give the core");
+        System.out.println("    file, and associated executable, to operate on. Otherwise the --pid");
+        System.out.println("    option can be set to operate on a live process.");
+        System.out.println("    The arguments for --exe and --core can use absolute or relative paths.");
+        System.out.println();
+        System.out.println("    Examples: jhsdb " + mode + " --pid 1234");
+        System.out.println("          or  jhsdb " + mode + " --core ./core.1234 --exe ./myexe");
         return false;
     }
 
     private static boolean debugdHelp() {
         // [options] <pid> [server-id]
         // [options] <executable> <core> [server-id]
-        System.out.println("    --serverid\t<unique id for this debug server>");
-        return commonHelp();
+        System.out.println("    --serverid <id>  \tA unique identifier for this debug server.");
+        return commonHelp("debugd");
     }
 
     private static boolean jinfoHelp() {
         // --flags -> -flags
         // --sysprops -> -sysprops
-        System.out.println("    --flags\tto print VM flags");
-        System.out.println("    --sysprops\tto print Java System properties");
-        System.out.println("    <no option>\tto print both of the above");
-        return commonHelp();
+        System.out.println("    --flags          \tTo print VM flags.");
+        System.out.println("    --sysprops       \tTo print Java System properties.");
+        System.out.println("    <no option>      \tTo print both of the above.");
+        return commonHelp("jinfo");
     }
 
     private static boolean jmapHelp() {
@@ -78,27 +86,27 @@
         // --clstats -> -clstats
         // --finalizerinfo -> -finalizerinfo
 
-        System.out.println("    <no option>\tto print same info as Solaris pmap");
-        System.out.println("    --heap\tto print java heap summary");
-        System.out.println("    --binaryheap\tto dump java heap in hprof binary format");
-        System.out.println("    --dumpfile\tname of the dump file");
-        System.out.println("    --histo\tto print histogram of java object heap");
-        System.out.println("    --clstats\tto print class loader statistics");
-        System.out.println("    --finalizerinfo\tto print information on objects awaiting finalization");
-        return commonHelp();
+        System.out.println("    <no option>      \tTo print same info as Solaris pmap.");
+        System.out.println("    --heap           \tTo print java heap summary.");
+        System.out.println("    --binaryheap     \tTo dump java heap in hprof binary format.");
+        System.out.println("    --dumpfile <name>\tThe name of the dump file.");
+        System.out.println("    --histo          \tTo print histogram of java object heap.");
+        System.out.println("    --clstats        \tTo print class loader statistics.");
+        System.out.println("    --finalizerinfo  \tTo print information on objects awaiting finalization.");
+        return commonHelp("jmap");
     }
 
     private static boolean jstackHelp() {
         // --locks -> -l
         // --mixed -> -m
-        System.out.println("    --locks\tto print java.util.concurrent locks");
-        System.out.println("    --mixed\tto print both java and native frames (mixed mode)");
-        return commonHelp();
+        System.out.println("    --locks          \tTo print java.util.concurrent locks.");
+        System.out.println("    --mixed          \tTo print both Java and native frames (mixed mode).");
+        return commonHelp("jstack");
     }
 
     private static boolean jsnapHelp() {
-        System.out.println("    --all\tto print all performance counters");
-        return commonHelp();
+        System.out.println("    --all            \tTo print all performance counters.");
+        return commonHelp("jsnap");
     }
 
     private static boolean toolHelp(String toolName) {
@@ -117,8 +125,11 @@
         if (toolName.equals("debugd")) {
             return debugdHelp();
         }
-        if (toolName.equals("hsdb") || toolName.equals("clhsdb")) {
-            return commonHelp();
+        if (toolName.equals("hsdb")) {
+            return commonHelp("hsdb");
+        }
+        if (toolName.equals("clhsdb")) {
+            return commonHelp("clhsdb");
         }
         return launcherHelp();
     }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java	Thu May 23 22:12:31 2019 +0200
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java	Thu May 30 19:49:55 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.Elements;
 import javax.lang.model.util.SimpleElementVisitor9;
@@ -564,7 +565,6 @@
     boolean allowInheritedMethods(ExecutableElement inheritedMethod,
                                   Map<ExecutableElement, List<ExecutableElement>> inheritedOverriddenTable,
                                   LocalMemberTable lmt) {
-
         if (!isInherited(inheritedMethod))
             return false;
 
@@ -598,7 +598,8 @@
 
         // Check the local methods in this type.
         List<Element> lMethods = lmt.getMembers(inheritedMethod, Kind.METHODS);
-        for (Element lMethod : lMethods) {
+        for (Element le : lMethods) {
+            ExecutableElement lMethod = (ExecutableElement) le;
             // Ignore private methods or those methods marked with
             // a "hidden" tag.
             if (utils.isPrivate(lMethod))
@@ -611,18 +612,26 @@
             }
 
             // Check for overriding methods.
-            if (elementUtils.overrides((ExecutableElement)lMethod, inheritedMethod,
+            if (elementUtils.overrides(lMethod, inheritedMethod,
                     utils.getEnclosingTypeElement(lMethod))) {
 
                 // Disallow package-private super methods to leak in
                 TypeElement encl = utils.getEnclosingTypeElement(inheritedMethod);
                 if (isUndocumentedEnclosure(encl)) {
-                    overriddenMethodTable.computeIfAbsent((ExecutableElement)lMethod,
+                    overriddenMethodTable.computeIfAbsent(lMethod,
                             l -> new OverridingMethodInfo(inheritedMethod, false));
                     return false;
                 }
-                boolean simpleOverride = utils.isSimpleOverride((ExecutableElement)lMethod);
-                overriddenMethodTable.computeIfAbsent((ExecutableElement)lMethod,
+
+                TypeMirror inheritedMethodReturn = inheritedMethod.getReturnType();
+                TypeMirror lMethodReturn = lMethod.getReturnType();
+                boolean covariantReturn =
+                        lMethodReturn.getKind() == TypeKind.DECLARED
+                        && inheritedMethodReturn.getKind() == TypeKind.DECLARED
+                        && !utils.typeUtils.isSameType(lMethodReturn, inheritedMethodReturn)
+                        && utils.typeUtils.isSubtype(lMethodReturn, inheritedMethodReturn);
+                boolean simpleOverride = covariantReturn ? false : utils.isSimpleOverride(lMethod);
+                overriddenMethodTable.computeIfAbsent(lMethod,
                         l -> new OverridingMethodInfo(inheritedMethod, simpleOverride));
                 return simpleOverride;
             }
@@ -987,5 +996,10 @@
             this.overrider = overrider;
             this.simpleOverride = simpleOverride;
         }
+
+        @Override
+        public String toString() {
+            return "OverridingMethodInfo[" + overrider + ",simple:" + simpleOverride + "]";
+        }
     }
 }
--- a/test/fmw/gtest/CHANGES	Thu May 23 22:12:31 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-Changes for 1.7.0:
-
-* New feature: death tests are supported on OpenBSD and in iOS
-  simulator now.
-* New feature: Google Test now implements a protocol to allow
-  a test runner to detect that a test program has exited
-  prematurely and report it as a failure (before it would be
-  falsely reported as a success if the exit code is 0).
-* New feature: Test::RecordProperty() can now be used outside of the
-  lifespan of a test method, in which case it will be attributed to
-  the current test case or the test program in the XML report.
-* New feature (potentially breaking): --gtest_list_tests now prints
-  the type parameters and value parameters for each test.
-* Improvement: char pointers and char arrays are now escaped properly
-  in failure messages.
-* Improvement: failure summary in XML reports now includes file and
-  line information.
-* Improvement: the <testsuites> XML element now has a timestamp attribute.
-* Improvement: When --gtest_filter is specified, XML report now doesn't
-  contain information about tests that are filtered out.
-* Fixed the bug where long --gtest_filter flag values are truncated in
-  death tests.
-* Potentially breaking change: RUN_ALL_TESTS() is now implemented as a
-  function instead of a macro in order to work better with Clang.
-* Compatibility fixes with C++ 11 and various platforms.
-* Bug/warning fixes.
-
-Changes for 1.6.0:
-
-* New feature: ADD_FAILURE_AT() for reporting a test failure at the
-  given source location -- useful for writing testing utilities.
-* New feature: the universal value printer is moved from Google Mock
-  to Google Test.
-* New feature: type parameters and value parameters are reported in
-  the XML report now.
-* A gtest_disable_pthreads CMake option.
-* Colored output works in GNU Screen sessions now.
-* Parameters of value-parameterized tests are now printed in the
-  textual output.
-* Failures from ad hoc test assertions run before RUN_ALL_TESTS() are
-  now correctly reported.
-* Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to
-  ostream.
-* More complete handling of exceptions.
-* GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter
-  name is already used by another library.
-* --gtest_catch_exceptions is now true by default, allowing a test
-  program to continue after an exception is thrown.
-* Value-parameterized test fixtures can now derive from Test and
-  WithParamInterface<T> separately, easing conversion of legacy tests.
-* Death test messages are clearly marked to make them more
-  distinguishable from other messages.
-* Compatibility fixes for Android, Google Native Client, MinGW, HP UX,
-  PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear),
-  IBM XL C++ (Visual Age C++), and C++0x.
-* Bug fixes and implementation clean-ups.
-* Potentially incompatible changes: disables the harmful 'make install'
-  command in autotools.
-
-Changes for 1.5.0:
-
- * New feature: assertions can be safely called in multiple threads
-   where the pthreads library is available.
- * New feature: predicates used inside EXPECT_TRUE() and friends
-   can now generate custom failure messages.
- * New feature: Google Test can now be compiled as a DLL.
- * New feature: fused source files are included.
- * New feature: