Merge niosocketimpl-branch
authoralanb
Thu, 24 Jan 2019 17:29:21 +0000
branchniosocketimpl-branch
changeset 57112 d7b54daf5e1a
parent 57111 a57c4dc7e2fe (current diff)
parent 53473 9366628d727b (diff)
child 57113 c775204f9dbe
Merge
src/java.base/share/classes/java/net/HttpConnectSocketImpl.java
src/java.base/share/classes/java/net/SocksSocketImpl.java
test/Makefile
test/TestCommon.gmk
test/hotspot/jtreg/Makefile
test/jaxp/Makefile
test/jdk/Makefile
test/langtools/Makefile
test/nashorn/Makefile
--- a/.hgtags	Thu Jan 24 17:11:10 2019 +0000
+++ b/.hgtags	Thu Jan 24 17:29:21 2019 +0000
@@ -537,3 +537,4 @@
 a47b8125b7cc9ef59619745c163975fe935b57ed jdk-13+4
 659b004b6a1bd8c31e766cbdf328d8f8473fd4d7 jdk-12+28
 
+e3ed960609927b5fdfd0a797159835cd83a81a31 jdk-13+5
--- a/doc/testing.html	Thu Jan 24 17:11:10 2019 +0000
+++ b/doc/testing.html	Thu Jan 24 17:29:21 2019 +0000
@@ -34,6 +34,7 @@
 </ul></li>
 <li><a href="#test-results-and-summary">Test results and summary</a></li>
 <li><a href="#test-suite-control">Test suite control</a><ul>
+<li><a href="#general-keywords-test_opts">General keywords (TEST_OPTS)</a></li>
 <li><a href="#jtreg-keywords">JTReg keywords</a></li>
 <li><a href="#gtest-keywords">Gtest keywords</a></li>
 <li><a href="#microbenchmark-keywords">Microbenchmark keywords</a></li>
@@ -102,11 +103,29 @@
 <p>To separate multiple keyword=value pairs, use <code>;</code> (semicolon). Since the shell normally eats <code>;</code>, the recommended usage is to write the assignment inside qoutes, e.g. <code>JTREG=&quot;...;...&quot;</code>. This will also make sure spaces are preserved, as in <code>JTREG=&quot;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug&quot;</code>.</p>
 <p>(Other ways are possible, e.g. using backslash: <code>JTREG=JOBS=1\;TIMEOUT=8</code>. Also, as a special technique, the string <code>%20</code> will be replaced with space for certain options, e.g. <code>JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)</p>
 <p>As far as possible, the names of the keywords have been standardized between test suites.</p>
+<h3 id="general-keywords-test_opts">General keywords (TEST_OPTS)</h3>
+<p>Some keywords are valid across different test suites. If you want to run tests from multiple test suites, or just don't want to care which test suite specific control variable to use, then you can use the general TEST_OPTS control variable.</p>
+<p>There are also some keywords that applies globally to the test runner system, not to any specific test suites. These are also available as TEST_OPTS keywords.</p>
+<h4 id="jobs">JOBS</h4>
+<p>Currently only applies to JTReg.</p>
+<h4 id="timeout_factor">TIMEOUT_FACTOR</h4>
+<p>Currently only applies to JTReg.</p>
+<h4 id="vm_options">VM_OPTIONS</h4>
+<p>Applies to JTReg, GTest and Micro.</p>
+<h4 id="java_options">JAVA_OPTIONS</h4>
+<p>Applies to JTReg, GTest and Micro.</p>
+<h4 id="aot_modules">AOT_MODULES</h4>
+<p>Applies to JTReg and GTest.</p>
+<h4 id="jcov">JCOV</h4>
+<p>This keywords applies globally to the test runner system. If set to <code>true</code>, it enables JCov coverage reporting for all tests run. To be useful, the JDK under test must be run with a JDK built with JCov instrumentation (<code>configure --with-jcov=&lt;path to directory containing lib/jcov.jar&gt;</code>, <code>make jcov-image</code>).</p>
+<p>The simplest way to run tests with JCov coverage report is to use the special target <code>jcov-test</code> instead of <code>test</code>, e.g. <code>make jcov-test TEST=jdk_lang</code>. This will make sure the JCov image is built, and that JCov reporting is enabled.</p>
+<p>The JCov report is stored in <code>build/$BUILD/test-results/jcov-output</code>.</p>
+<p>Please note that running with JCov reporting can be very memory intensive.</p>
 <h3 id="jtreg-keywords">JTReg keywords</h3>
-<h4 id="jobs">JOBS</h4>
+<h4 id="jobs-1">JOBS</h4>
 <p>The test concurrency (<code>-concurrency</code>).</p>
 <p>Defaults to TEST_JOBS (if set by <code>--with-test-jobs=</code>), otherwise it defaults to JOBS, except for Hotspot, where the default is <em>number of CPU cores/2</em>, but never more than 12.</p>
-<h4 id="timeout">TIMEOUT</h4>
+<h4 id="timeout_factor-1">TIMEOUT_FACTOR</h4>
 <p>The timeout factor (<code>-timeoutFactor</code>).</p>
 <p>Defaults to 4.</p>
 <h4 id="test_mode">TEST_MODE</h4>
@@ -125,13 +144,21 @@
 <p>Limit memory consumption (<code>-Xmx</code> and <code>-vmoption:-Xmx</code>, or none).</p>
 <p>Limit memory consumption for JTReg test framework and VM under test. Set to 0 to disable the limits.</p>
 <p>Defaults to 512m, except for hotspot, where it defaults to 0 (no limit).</p>
+<h4 id="keywords">KEYWORDS</h4>
+<p>JTReg kewords sent to JTReg using <code>-k</code>. Please be careful in making sure that spaces and special characters (like <code>!</code>) are properly quoted. To avoid some issues, the special value <code>%20</code> can be used instead of space.</p>
+<h4 id="extra_problem_lists">EXTRA_PROBLEM_LISTS</h4>
+<p>Use additional problem lists file or files, in addition to the default ProblemList.txt located at the JTReg test roots.</p>
+<p>If multiple file names are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
+<p>The file names should be either absolute, or relative to the JTReg test root of the tests to be run.</p>
 <h4 id="options">OPTIONS</h4>
 <p>Additional options to the JTReg test framework.</p>
 <p>Use <code>JTREG=&quot;OPTIONS=--help all&quot;</code> to see all available JTReg options.</p>
-<h4 id="java_options">JAVA_OPTIONS</h4>
+<h4 id="java_options-1">JAVA_OPTIONS</h4>
 <p>Additional Java options to JTReg (<code>-javaoption</code>).</p>
-<h4 id="vm_options">VM_OPTIONS</h4>
+<h4 id="vm_options-1">VM_OPTIONS</h4>
 <p>Additional VM options to JTReg (<code>-vmoption</code>).</p>
+<h4 id="aot_modules-1">AOT_MODULES</h4>
+<p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
 <h3 id="gtest-keywords">Gtest keywords</h3>
 <h4 id="repeat">REPEAT</h4>
 <p>The number of times to repeat the tests (<code>--gtest_repeat</code>).</p>
@@ -139,6 +166,8 @@
 <h4 id="options-1">OPTIONS</h4>
 <p>Additional options to the Gtest test framework.</p>
 <p>Use <code>GTEST=&quot;OPTIONS=--help&quot;</code> to see all available Gtest options.</p>
+<h4 id="aot_modules-2">AOT_MODULES</h4>
+<p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
 <h3 id="microbenchmark-keywords">Microbenchmark keywords</h3>
 <h4 id="fork">FORK</h4>
 <p>Override the number of benchmark forks to spawn. Same as specifying <code>-f &lt;num&gt;</code>.</p>
@@ -152,7 +181,7 @@
 <p>Amount of time to spend in each warmup iteration. Same as specifying <code>-w &lt;num&gt;</code>.</p>
 <h4 id="results_format">RESULTS_FORMAT</h4>
 <p>Specify to have the test run save a log of the values. Accepts the same values as <code>-rff</code>, i.e., <code>text</code>, <code>csv</code>, <code>scsv</code>, <code>json</code>, or <code>latex</code>.</p>
-<h4 id="vm_options-1">VM_OPTIONS</h4>
+<h4 id="vm_options-2">VM_OPTIONS</h4>
 <p>Additional VM arguments to provide to forked off VMs. Same as <code>-jvmArgs &lt;args&gt;</code></p>
 <h4 id="options-2">OPTIONS</h4>
 <p>Additional arguments to send to JMH.</p>
--- a/doc/testing.md	Thu Jan 24 17:11:10 2019 +0000
+++ b/doc/testing.md	Thu Jan 24 17:29:21 2019 +0000
@@ -40,8 +40,8 @@
 
 To be able to run microbenchmarks, `configure` needs to know where to find
 the JMH dependency. Use `--with-jmh=<path to JMH jars>` to point to a directory
-containing the core JMH and transitive dependencies. The recommended dependencies 
-can be retrieved by running `sh make/devkit/createJMHBundle.sh`, after which 
+containing the core JMH and transitive dependencies. The recommended dependencies
+can be retrieved by running `sh make/devkit/createJMHBundle.sh`, after which
 `--with-jmh=build/jmh/jars` should work.
 
 ## Test selection
@@ -202,6 +202,50 @@
 As far as possible, the names of the keywords have been standardized between
 test suites.
 
+### General keywords (TEST_OPTS)
+
+Some keywords are valid across different test suites. If you want to run
+tests from multiple test suites, or just don't want to care which test suite specific
+control variable to use, then you can use the general TEST_OPTS control variable.
+
+There are also some keywords that applies globally to the test runner system,
+not to any specific test suites. These are also available as TEST_OPTS keywords.
+
+#### JOBS
+
+Currently only applies to JTReg.
+
+#### TIMEOUT_FACTOR
+
+Currently only applies to JTReg.
+
+#### VM_OPTIONS
+
+Applies to JTReg, GTest and Micro.
+
+#### JAVA_OPTIONS
+
+Applies to JTReg, GTest and Micro.
+
+#### AOT_MODULES
+
+Applies to JTReg and GTest.
+
+#### JCOV
+
+This keywords applies globally to the test runner system. If set to `true`, it
+enables JCov coverage reporting for all tests run. To be useful, the JDK under
+test must be run with a JDK built with JCov instrumentation (`configure
+--with-jcov=<path to directory containing lib/jcov.jar>`, `make jcov-image`).
+
+The simplest way to run tests with JCov coverage report is to use the special
+target `jcov-test` instead of `test`, e.g. `make jcov-test TEST=jdk_lang`. This
+will make sure the JCov image is built, and that JCov reporting is enabled.
+
+The JCov report is stored in `build/$BUILD/test-results/jcov-output`.
+
+Please note that running with JCov reporting can be very memory intensive.
+
 ### JTReg keywords
 
 #### JOBS
@@ -211,7 +255,7 @@
 JOBS, except for Hotspot, where the default is *number of CPU cores/2*, but
 never more than 12.
 
-#### TIMEOUT
+#### TIMEOUT_FACTOR
 The timeout factor (`-timeoutFactor`).
 
 Defaults to 4.
@@ -245,6 +289,24 @@
 
 Defaults to 512m, except for hotspot, where it defaults to 0 (no limit).
 
+#### KEYWORDS
+
+JTReg kewords sent to JTReg using `-k`. Please be careful in making sure that
+spaces and special characters (like `!`) are properly quoted. To avoid some
+issues, the special value `%20` can be used instead of space.
+
+#### EXTRA_PROBLEM_LISTS
+
+Use additional problem lists file or files, in addition to the default
+ProblemList.txt located at the JTReg test roots.
+
+If multiple file names are specified, they should be separated by space (or, to
+help avoid quoting issues, the special value `%20`).
+
+The file names should be either absolute, or relative to the JTReg test root of
+the tests to be run.
+
+
 #### OPTIONS
 Additional options to the JTReg test framework.
 
@@ -256,6 +318,12 @@
 #### VM_OPTIONS
 Additional VM options to JTReg (`-vmoption`).
 
+#### AOT_MODULES
+
+Generate AOT modules before testing for the specified module, or set of
+modules. If multiple modules are specified, they should be separated by space
+(or, to help avoid quoting issues, the special value `%20`).
+
 ### Gtest keywords
 
 #### REPEAT
@@ -270,6 +338,12 @@
 
 Use `GTEST="OPTIONS=--help"` to see all available Gtest options.
 
+#### AOT_MODULES
+
+Generate AOT modules before testing for the specified module, or set of
+modules. If multiple modules are specified, they should be separated by space
+(or, to help avoid quoting issues, the special value `%20`).
+
 ### Microbenchmark keywords
 
 #### FORK
--- a/make/Main.gmk	Thu Jan 24 17:11:10 2019 +0000
+++ b/make/Main.gmk	Thu Jan 24 17:29:21 2019 +0000
@@ -479,10 +479,11 @@
 
 define DeclareRunTestRecipe
   test-$1:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk run-test TEST="$1")
+	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk \
+	    TEST="$1")
 
   exploded-test-$1:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk run-test \
+	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk \
 	    TEST="$1" JDK_IMAGE_DIR=$(JDK_OUTPUTDIR))
 endef
 
@@ -490,21 +491,11 @@
 $(foreach t, $(ALL_NAMED_TESTS), $(eval $(call DeclareRunTestRecipe,$t)))
 ALL_TEST_TARGETS := $(addprefix test-, $(ALL_NAMED_TESTS))
 
-define DeclareRunJCovTestRecipe
-  jcov-test-$1:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk \
-	    TEST="$1" TEST_OPTS_JCOV=true)
-endef
-
-# jcov-test only makes sense for some of the tests
-$(foreach t, $(JCOV_NAMED_TESTS), $(eval $(call DeclareRunJCovTestRecipe,$t)))
-ALL_JCOV_TEST_TARGETS := $(addprefix jcov-test-, $(JCOV_NAMED_TESTS))
-
 # We only support the "exploded-test-gtest" shortcut
 ALL_EXPLODED_TESTS := gtest
 ALL_EXPLODED_TEST_TARGETS := $(addprefix exploded-test-, $(ALL_EXPLODED_TESTS))
 
-ALL_TARGETS += $(ALL_TEST_TARGETS) $(ALL_EXPLODED_TEST_TARGETS) $(ALL_JCOV_TEST_TARGETS)
+ALL_TARGETS += $(ALL_TEST_TARGETS) $(ALL_EXPLODED_TEST_TARGETS)
 
 ################################################################################
 # Build tests and microbenchmarks
@@ -571,10 +562,11 @@
 # Run tests
 
 test:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk run-test TEST="$(TEST)")
+	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk \
+	    TEST="$(TEST)")
 
 exploded-test:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk run-test \
+	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk \
 	    TEST="$(TEST)" JDK_IMAGE_DIR=$(JDK_OUTPUTDIR))
 
 jcov-test:
@@ -891,7 +883,6 @@
   # Declare dependency for all generated test targets
   $(foreach t, $(filter-out test-make%, $(ALL_TEST_TARGETS)), $(eval $t: jdk-image test-image))
   $(foreach t, $(ALL_EXPLODED_TEST_TARGETS), $(eval $t: exploded-image test-image))
-  $(ALL_JCOV_TEST_TARGETS): jcov-image test-image
 
   create-buildjdk-copy: jdk.jlink-java java.base-gendata \
       $(addsuffix -java, $(INTERIM_IMAGE_MODULES))
--- a/make/RunTests.gmk	Thu Jan 24 17:11:10 2019 +0000
+++ b/make/RunTests.gmk	Thu Jan 24 17:29:21 2019 +0000
@@ -45,8 +45,8 @@
 endif
 
 $(eval $(call ParseKeywordVariable, TEST_OPTS, \
-    SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR AOT_MODULES JCOV, \
-    STRING_KEYWORDS := VM_OPTIONS JAVA_OPTIONS, \
+    SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR JCOV, \
+    STRING_KEYWORDS := VM_OPTIONS JAVA_OPTIONS AOT_MODULES, \
 ))
 
 # Helper function to propagate TEST_OPTS values.
@@ -104,8 +104,10 @@
       -timeoutHandlerTimeout:0
 endif
 
-GTEST_LAUNCHER_DIRS := $(patsubst %/gtestLauncher, %, $(wildcard $(TEST_IMAGE_DIR)/hotspot/gtest/*/gtestLauncher))
-GTEST_VARIANTS := $(strip $(patsubst $(TEST_IMAGE_DIR)/hotspot/gtest/%, %, $(GTEST_LAUNCHER_DIRS)))
+GTEST_LAUNCHER_DIRS := $(patsubst %/gtestLauncher, %, \
+    $(wildcard $(TEST_IMAGE_DIR)/hotspot/gtest/*/gtestLauncher))
+GTEST_VARIANTS := $(strip $(patsubst $(TEST_IMAGE_DIR)/hotspot/gtest/%, %, \
+    $(GTEST_LAUNCHER_DIRS)))
 
 ################################################################################
 # Optionally create AOT libraries for specified modules before running tests.
@@ -129,19 +131,14 @@
   $1_AOT_LIB := $$($1_BIN)/$$(call SHARED_LIBRARY,$$($1_MODULE))
   $1_AOT_CCLIST := $$(wildcard $$(TOPDIR)/test/hotspot/jtreg/compiler/aot/scripts/$$($1_MODULE)-list.txt)
 
-  ifeq ($(OPENJDK_TARGET_OS), windows)
-    $1_LD := $$(addsuffix $$(EXE_SUFFIX), $$(filter-out $$(FIXPATH), $$(LD)))
-  else
-    $1_LD := $$(LD)
-  endif
-
   # Create jaotc flags.
-  # VM flags which don't affect AOT code generation are filtered out: -Xcomp, -XX:+-TieredCompilation
+  # VM flags which don't affect AOT code generation are filtered out:
+  # -Xcomp, -XX:+-TieredCompilation
   $1_JAOTC_OPTS := \
       -J-Xmx4g --info \
       $$(addprefix -J, $$(filter-out -Xcomp %TieredCompilation, $$($1_VM_OPTIONS))) \
       $$(addprefix --compile-commands$(SPACE), $$($1_AOT_CCLIST)) \
-      --linker-path $$($1_LD) \
+      --linker-path $$(LD_JAOTC) \
       #
 
   ifneq ($$(filter -ea, $$($1_VM_OPTIONS)), )
@@ -155,12 +152,14 @@
 	$$(call MakeTargetDir)
 	$$(call ExecuteWithLog, $$@, \
 	    $$(FIXPATH) $$(JDK_IMAGE_DIR)/bin/jaotc \
-	    $$($1_JAOTC_OPTS) --output $$@ --module $$($1_MODULE) \
+	        $$($1_JAOTC_OPTS) --output $$@ --module $$($1_MODULE) \
 	)
 	$$(call ExecuteWithLog, $$@.check, \
-	  $$(FIXPATH) $$(JDK_IMAGE_DIR)/bin/java \
-	  $$($1_VM_OPTIONS) -XX:+PrintAOT -XX:+UseAOTStrictLoading -XX:AOTLibrary=$$@ -version \
-	  > $$@.verify-aot \
+	    $$(FIXPATH) $$(JDK_IMAGE_DIR)/bin/java \
+	        $$($1_VM_OPTIONS) -XX:+UnlockDiagnosticVMOptions \
+	        -XX:+PrintAOT -XX:+UseAOTStrictLoading \
+	        -XX:AOTLibrary=$$@ -version \
+	         > $$@.verify-aot \
 	)
 
   $1_AOT_OPTIONS += -XX:AOTLibrary=$$($1_AOT_LIB)
@@ -249,9 +248,10 @@
 $(eval $(call SetTestOpt,TIMEOUT_FACTOR,JTREG))
 
 $(eval $(call ParseKeywordVariable, JTREG, \
-    SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR TEST_MODE ASSERT VERBOSE RETAIN MAX_MEM \
-        EXTRA_PROBLEM_LISTS KEYWORDS AOT_MODULES, \
-    STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS, \
+    SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR TEST_MODE ASSERT VERBOSE RETAIN \
+        MAX_MEM, \
+    STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS KEYWORDS \
+        EXTRA_PROBLEM_LISTS AOT_MODULES, \
 ))
 
 ifneq ($(JTREG), )
@@ -266,8 +266,8 @@
 $(eval $(call SetTestOpt,AOT_MODULES,GTEST))
 
 $(eval $(call ParseKeywordVariable, GTEST, \
-    SINGLE_KEYWORDS := REPEAT AOT_MODULES, \
-    STRING_KEYWORDS := OPTIONS VM_OPTIONS JAVA_OPTIONS, \
+    SINGLE_KEYWORDS := REPEAT, \
+    STRING_KEYWORDS := OPTIONS VM_OPTIONS JAVA_OPTIONS AOT_MODULES, \
 ))
 
 ifneq ($(GTEST), )
@@ -282,7 +282,8 @@
 
 $(eval $(call ParseKeywordVariable, MICRO, \
     SINGLE_KEYWORDS := ITER FORK TIME WARMUP_ITER WARMUP_TIME, \
-    STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS RESULTS_FORMAT TEST_JDK BENCHMARKS_JAR, \
+    STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS RESULTS_FORMAT TEST_JDK \
+        BENCHMARKS_JAR, \
 ))
 
 ifneq ($(MICRO), )
@@ -348,8 +349,8 @@
 
 # Helper function to determine if a test specification is a microbenchmark test
 #
-# It is a microbenchmark test if it is either "micro", or "micro:" followed by an optional
-# test filter string.
+# It is a microbenchmark test if it is either "micro", or "micro:" followed by
+# an optional test filter string.
 define ParseMicroTestSelection
   $(if $(filter micro%, $1), \
     $(if $(filter micro, $1), \
@@ -439,8 +440,8 @@
 # Helper function to determine if a test specification is a special test
 #
 # It is a special test if it is "special:" followed by a test name,
-# if it is "make:" or "make-" followed by a make test, or any of the special test names
-# as a single word.
+# if it is "make:" or "make-" followed by a make test, or any of the special
+# test names as a single word.
 define ParseSpecialTestSelection
   $(if $(filter special:%, $1), \
     $1 \
@@ -555,7 +556,7 @@
     ))
   endif
 
-  run-test-$1: $$($1_AOT_TARGETS)
+  run-test-$1: pre-run-test $$($1_AOT_TARGETS)
 	$$(call LogWarn)
 	$$(call LogWarn, Running test '$$($1_TEST)')
 	$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
@@ -595,7 +596,11 @@
 	  $$(eval $1_TOTAL := 1) \
 	)
 
-  TARGETS += run-test-$1 parse-test-$1
+  $1: run-test-$1 parse-test-$1
+
+  TARGETS += $1 run-test-$1 parse-test-$1
+  TEST_TARGETS += parse-test-$1
+
 endef
 
 ################################################################################
@@ -637,7 +642,8 @@
 
   # Save output as JSON or CSV file
   ifneq ($$(MICRO_RESULTS_FORMAT), )
-    $1_MICRO_BASIC_OPTIONS += -rf $$(MICRO_RESULTS_FORMAT) -rff $$($1_TEST_RESULTS_DIR)/jmh-result.$(MICRO_RESULTS_FORMAT)
+    $1_MICRO_BASIC_OPTIONS += -rf $$(MICRO_RESULTS_FORMAT)
+    $1_MICRO_BASIC_OPTIONS += -rff $$($1_TEST_RESULTS_DIR)/jmh-result.$(MICRO_RESULTS_FORMAT)
   endif
 
   ifneq ($$(MICRO_VM_OPTIONS)$$(MICRO_JAVA_OPTIONS), )
@@ -660,7 +666,7 @@
     $1_MICRO_WARMUP_TIME := -w $$(MICRO_WARMUP_TIME)
   endif
 
-  run-test-$1:
+  run-test-$1: pre-run-test
 	$$(call LogWarn)
 	$$(call LogWarn, Running test '$$($1_TEST)')
 	$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
@@ -668,7 +674,7 @@
 	    $$($1_MICRO_TEST_JDK)/bin/java $$($1_MICRO_JAVA_OPTIONS) -jar $$($1_MICRO_BENCHMARKS_JAR) \
 	        $$($1_MICRO_ITER) $$($1_MICRO_FORK) $$($1_MICRO_TIME) \
 	        $$($1_MICRO_WARMUP_ITER) $$($1_MICRO_WARMUP_TIME) \
-	        $$($1_MICRO_VM_OPTIONS) $$($1_MICRO_BASIC_OPTIONS) $$(MICRO_OPTIONS)  \
+	        $$($1_MICRO_VM_OPTIONS) $$($1_MICRO_BASIC_OPTIONS) $$(MICRO_OPTIONS) \
 	        $$($1_TEST_NAME) \
 	        > >($(TEE) $$($1_TEST_RESULTS_DIR)/micro.txt) \
 	    && $$(ECHO) $$$$? > $$($1_EXITCODE) \
@@ -700,7 +706,11 @@
 	  $$(eval $1_TOTAL := 1) \
 	)
 
-  TARGETS += run-test-$1 parse-test-$1
+  $1: run-test-$1 parse-test-$1
+
+  TARGETS += $1 run-test-$1 parse-test-$1
+  TEST_TARGETS += parse-test-$1
+
 endef
 
 ################################################################################
@@ -870,7 +880,7 @@
   clean-workdir-$1:
 	$$(RM) -r $$($1_TEST_SUPPORT_DIR)
 
-  run-test-$1: clean-workdir-$1 $$($1_AOT_TARGETS)
+  run-test-$1: pre-run-test clean-workdir-$1 $$($1_AOT_TARGETS)
 	$$(call LogWarn)
 	$$(call LogWarn, Running test '$$($1_TEST)')
 	$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
@@ -919,7 +929,11 @@
 	  $$(eval $1_TOTAL := 1) \
 	)
 
-  TARGETS += run-test-$1 parse-test-$1
+  $1: run-test-$1 parse-test-$1 clean-workdir-$1
+
+  TARGETS += $1 run-test-$1 parse-test-$1 clean-workdir-$1
+  TEST_TARGETS += parse-test-$1
+
 endef
 
 ################################################################################
@@ -957,7 +971,7 @@
     $$(error Invalid special test specification: $$($1_TEST_NAME))
   endif
 
-  run-test-$1: $(TEST_PREREQS)
+  run-test-$1: pre-run-test
 	$$(call LogWarn)
 	$$(call LogWarn, Running test '$$($1_TEST)')
 	$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
@@ -981,7 +995,11 @@
 	$$(eval $1_ERROR := 0)
 	$$(eval $1_TOTAL := 0)
 
-  TARGETS += run-test-$1 parse-test-$1
+  $1: run-test-$1 parse-test-$1
+
+  TARGETS += $1 run-test-$1 parse-test-$1
+  TEST_TARGETS += parse-test-$1
+
 endef
 
 ################################################################################
@@ -1043,12 +1061,36 @@
 # The main target for RunTests.gmk
 ################################################################################
 
-# The SetupRun*Test functions have populated TARGETS.
+#
+# Provide hooks for adding functionality before and after all tests are run.
+#
+
+$(call LogInfo, RunTest setup starting)
+
+# This target depends on all actual test having been run (TEST_TARGETS has beeen
+# populated by the SetupRun*Test functions). If you need to provide a teardown
+# hook, you must let it depend on this target.
+run-all-tests: $(TEST_TARGETS)
+	$(call LogInfo, RunTest teardown starting)
 
+# This is an abstract target that will be run before any actual tests. Add your
+# target as a dependency to thisif you need "setup" type functionality executed
+# before all tests.
+pre-run-test:
+	$(call LogInfo, RunTest setup done)
+
+# This is an abstract target that will be run after all actual tests, but before
+# the test summary. If you need "teardown" type functionality, add your target
+# as a dependency on this, and let the teardown target depend on run-all-tests.
+post-run-test: run-all-tests
+	$(call LogInfo, RunTest teardown done)
+
+#
+# Create and print a table of the result of all tests run
+#
 TEST_FAILURE := false
 
-run-test: $(TARGETS)
-        # Create and print a table of the result of all tests run
+run-test-report: post-run-test
 	$(RM) $(TEST_SUMMARY).old 2> /dev/null
 	$(MV) $(TEST_SUMMARY) $(TEST_SUMMARY).old 2> /dev/null || true
 	$(RM) $(TEST_LAST_IDS).old 2> /dev/null
@@ -1092,6 +1134,11 @@
 	$(CAT) $(TEST_SUMMARY)
 	$(ECHO)
 
+# The main run-test target
+run-test: run-test-report
+
+TARGETS += run-all-tests pre-run-test post-run-test run-test-report run-test
+
 ################################################################################
 # Setup JCov
 ################################################################################
@@ -1130,14 +1177,21 @@
 	$(call LogWarn, Stopping JCov Grabber...)
 	$(JAVA) -jar $(JCOV_HOME)/lib/jcov.jar GrabberManager -stop -stoptimeout 3600
 
-  jcov-gen-report: run-test jcov-stop-grabber
+  jcov-gen-report: jcov-stop-grabber
 	$(call LogWarn, Generating JCov report ...)
 	$(JAVA) -Xmx4g -jar $(JCOV_HOME)/lib/jcov.jar RepGen -sourcepath \
 	    `$(ECHO) $(TOPDIR)/src/*/share/classes/ | $(TR) ' ' ':'` -fmt html \
 	    -o $(JCOV_REPORT) $(JCOV_RESULT_FILE)
 
-  $(TARGETS): jcov-start-grabber
-  all: jcov-gen-report
+  TARGETS += jcov-do-start-grabber jcov-start-grabber jcov-stop-grabber \
+      jcov-gen-report
+
+  # Hook this into the framework at appropriate places
+  pre-run-test: jcov-start-grabber
+
+  post-run-test: jcov-gen-report
+
+  jcov-gen-report: run-all-tests
 
 endif
 
@@ -1145,4 +1199,4 @@
 
 all: run-test
 
-.PHONY: default all run-test $(TARGETS)
+.PHONY: default all $(TARGETS)
--- a/make/RunTestsPrebuilt.gmk	Thu Jan 24 17:11:10 2019 +0000
+++ b/make/RunTestsPrebuilt.gmk	Thu Jan 24 17:29:21 2019 +0000
@@ -254,26 +254,22 @@
 # Setup LD for AOT support
 ifneq ($(DEVKIT_HOME), )
   ifeq ($(OPENJDK_TARGET_OS), windows)
-    LD := $(DEVKIT_HOME)/VC/bin/x64/link
+    LD_JAOTC := $(DEVKIT_HOME)/VC/bin/x64/link.exe
     LIBRARY_PREFIX :=
     SHARED_LIBRARY_SUFFIX := .dll
-    EXE_SUFFIX := .exe
   else ifeq ($(OPENJDK_TARGET_OS), linux)
-    LD := $(DEVKIT_HOME)/bin/ld
+    LD_JAOTC := $(DEVKIT_HOME)/bin/ld
     LIBRARY_PREFIX := lib
     SHARED_LIBRARY_SUFFIX := .so
-    EXE_SUFFIX :=
   else ifeq ($(OPENJDK_TARGET_OS), macosx)
-    LD := $(DEVKIT_HOME)/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
+    LD_JAOTC := $(DEVKIT_HOME)/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
     LIBRARY_PREFIX := lib
     SHARED_LIBRARY_SUFFIX := .dylib
-    EXE_SUFFIX :=
   else ifeq ($(OPENJDK_TARGET_OS), solaris)
     # Prefer system linker for AOT on Solaris.
-    LD := ld
+    LD_JAOTC := ld
     LIBRARY_PREFIX := lib
     SHARED_LIBRARY_SUFFIX := .so
-    EXE_SUFFIX :=
   endif
 else
   LD := ld
@@ -315,10 +311,9 @@
     OPENJDK_TARGET_CPU_ENDIAN := $(OPENJDK_TARGET_CPU_ENDIAN), \
     NUM_CORES := $(NUM_CORES), \
     MEMORY_SIZE := $(MEMORY_SIZE), \
-    LD := $(LD), \
+    LD_JAOTC := $(LD_JAOTC), \
     LIBRARY_PREFIX := $(LIBRARY_PREFIX), \
     SHARED_LIBRARY_SUFFIX := $(SHARED_LIBRARY_SUFFIX), \
-    EXE_SUFFIX := $(EXE_SUFFIX), \
     include $(TOPDIR)/make/RunTestsPrebuiltSpec.gmk, \
     $(CUSTOM_NEW_SPEC_LINE), \
 )
--- a/make/autoconf/spec.gmk.in	Thu Jan 24 17:11:10 2019 +0000
+++ b/make/autoconf/spec.gmk.in	Thu Jan 24 17:29:21 2019 +0000
@@ -487,6 +487,9 @@
 # The linker can be gcc or ld on unix systems, or link.exe on windows systems.
 LD:=@FIXPATH@ @LD@
 
+# Linker used by the jaotc tool for AOT compilation.
+LD_JAOTC:=@LD_JAOTC@
+
 # Xcode SDK path
 SDKROOT:=@SDKROOT@
 
--- a/make/autoconf/toolchain.m4	Thu Jan 24 17:11:10 2019 +0000
+++ b/make/autoconf/toolchain.m4	Thu Jan 24 17:29:21 2019 +0000
@@ -715,12 +715,18 @@
       AC_MSG_RESULT([yes])
     fi
     LDCXX="$LD"
+    # jaotc being a windows program expects the linker to be supplied with exe suffix.
+    LD_JAOTC="$LD$EXE_SUFFIX"
   else
     # All other toolchains use the compiler to link.
     LD="$CC"
     LDCXX="$CXX"
+    # jaotc expects 'ld' as the linker rather than the compiler.
+    BASIC_CHECK_TOOLS([LD_JAOTC], ld)
+    BASIC_FIXUP_EXECUTABLE(LD_JAOTC)
   fi
   AC_SUBST(LD)
+  AC_SUBST(LD_JAOTC)
   # FIXME: it should be CXXLD, according to standard (cf CXXCPP)
   AC_SUBST(LDCXX)
 
--- a/make/common/FindTests.gmk	Thu Jan 24 17:11:10 2019 +0000
+++ b/make/common/FindTests.gmk	Thu Jan 24 17:29:21 2019 +0000
@@ -68,7 +68,6 @@
 # Add Jtreg test groups to list of named tests (test groups, test list, etc)
 # ALL_NAMED_TESTS might have been set by a custom extension
 ALL_NAMED_TESTS += $(JTREG_TEST_GROUPS)
-JCOV_NAMED_TESTS += $(JTREG_TEST_GROUPS)
 
 # Add Gtest
 ALL_NAMED_TESTS += gtest
--- a/src/hotspot/cpu/aarch64/aarch64.ad	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/cpu/aarch64/aarch64.ad	Thu Jan 24 17:29:21 2019 +0000
@@ -3417,37 +3417,21 @@
       __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont);
     }
 
-    // Handle existing monitor
+    // Check for existing monitor
     __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
 
-    // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
-    __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value);
-
-    // Load Compare Value application register.
+    // Set tmp to be (markOop of object | UNLOCK_VALUE).
+    __ orr(tmp, disp_hdr, markOopDesc::unlocked_value);
 
     // Initialize the box. (Must happen before we update the object mark!)
-    __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
-
-    // Compare object markOop with mark and if equal exchange scratch1
-    // with object markOop.
-    if (UseLSE) {
-      __ mov(tmp, disp_hdr);
-      __ casal(Assembler::xword, tmp, box, oop);
-      __ cmp(tmp, disp_hdr);
-      __ br(Assembler::EQ, cont);
-    } else {
-      Label retry_load;
-      if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
-        __ prfm(Address(oop), PSTL1STRM);
-      __ bind(retry_load);
-      __ ldaxr(tmp, oop);
-      __ cmp(tmp, disp_hdr);
-      __ br(Assembler::NE, cas_failed);
-      // use stlxr to ensure update is immediately visible
-      __ stlxr(tmp, box, oop);
-      __ cbzw(tmp, cont);
-      __ b(retry_load);
-    }
+    __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
+
+    // Compare object markOop with an unlocked value (tmp) and if
+    // equal exchange the stack address of our box with object markOop.
+    // On failure disp_hdr contains the possibly locked markOop.
+    __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
+               /*release*/ true, /*weak*/ false, disp_hdr);
+    __ br(Assembler::EQ, cont);
 
     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
 
@@ -3464,38 +3448,21 @@
     __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place));
     // If condition is true we are cont and hence we can store 0 as the
     // displaced header in the box, which indicates that it is a recursive lock.
-    __ ands(tmp/*==0?*/, disp_hdr, tmp);
+    __ ands(tmp/*==0?*/, disp_hdr, tmp);   // Sets flags for result
     __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
 
+    __ b(cont);
+
     // Handle existing monitor.
-    __ b(cont);
-
     __ bind(object_has_monitor);
+
     // The object's monitor m is unlocked iff m->owner == NULL,
     // otherwise m->owner may contain a thread or a stack address.
     //
     // Try to CAS m->owner from NULL to current thread.
     __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value));
-    __ mov(disp_hdr, zr);
-
-    if (UseLSE) {
-      __ mov(rscratch1, disp_hdr);
-      __ casal(Assembler::xword, rscratch1, rthread, tmp);
-      __ cmp(rscratch1, disp_hdr);
-    } else {
-      Label retry_load, fail;
-      if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) {
-        __ prfm(Address(tmp), PSTL1STRM);
-      }
-      __ bind(retry_load);
-      __ ldaxr(rscratch1, tmp);
-      __ cmp(disp_hdr, rscratch1);
-      __ br(Assembler::NE, fail);
-      // use stlxr to ensure update is immediately visible
-      __ stlxr(rscratch1, rthread, tmp);
-      __ cbnzw(rscratch1, retry_load);
-      __ bind(fail);
-    }
+    __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true,
+               /*release*/ true, /*weak*/ false, noreg); // Sets flags for result
 
     // Store a non-null value into the box to avoid looking like a re-entrant
     // lock. The fast-path monitor unlock code checks for
@@ -3539,24 +3506,9 @@
     // see the stack address of the basicLock in the markOop of the
     // object.
 
-    if (UseLSE) {
-      __ mov(tmp, box);
-      __ casl(Assembler::xword, tmp, disp_hdr, oop);
-      __ cmp(tmp, box);
-      __ b(cont);
-    } else {
-      Label retry_load;
-      if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
-        __ prfm(Address(oop), PSTL1STRM);
-      __ bind(retry_load);
-      __ ldxr(tmp, oop);
-      __ cmp(box, tmp);
-      __ br(Assembler::NE, cont);
-      // use stlxr to ensure update is immediately visible
-      __ stlxr(tmp, disp_hdr, oop);
-      __ cbzw(tmp, cont);
-      __ b(retry_load);
-    }
+    __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false,
+               /*release*/ true, /*weak*/ false, tmp);
+    __ b(cont);
 
     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
 
@@ -3567,13 +3519,13 @@
     __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes()));
     __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner.
     __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions
-    __ cmp(rscratch1, zr);
+    __ cmp(rscratch1, zr); // Sets flags for result
     __ br(Assembler::NE, cont);
 
     __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes()));
     __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes()));
     __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0.
-    __ cmp(rscratch1, zr);
+    __ cmp(rscratch1, zr); // Sets flags for result
     __ cbnz(rscratch1, cont);
     // need a release store here
     __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
--- a/src/hotspot/os/bsd/os_bsd.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -2565,7 +2565,7 @@
 
   // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
   while (true) {
-    if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+    if (sr_semaphore.timedwait(2)) {
       break;
     } else {
       // timeout
@@ -2599,7 +2599,7 @@
 
   while (true) {
     if (sr_notify(osthread) == 0) {
-      if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+      if (sr_semaphore.timedwait(2)) {
         if (osthread->sr.is_running()) {
           return;
         }
--- a/src/hotspot/os/bsd/semaphore_bsd.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/bsd/semaphore_bsd.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -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
@@ -24,6 +24,7 @@
 
 #include "precompiled/precompiled.hpp"
 #include "semaphore_bsd.hpp"
+#include "runtime/os.hpp"
 #include "utilities/debug.hpp"
 
 #include <semaphore.h>
@@ -65,29 +66,27 @@
   assert(ret == KERN_SUCCESS, "Failed to wait on semaphore");
 }
 
-int64_t OSXSemaphore::currenttime() {
-  struct timeval tv;
-  gettimeofday(&tv, NULL);
-  return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000);
+bool OSXSemaphore::trywait() {
+  return timedwait(0);
 }
 
-bool OSXSemaphore::trywait() {
-  return timedwait(0, 0);
-}
-
-bool OSXSemaphore::timedwait(unsigned int sec, int nsec) {
+bool OSXSemaphore::timedwait(int64_t millis) {
   kern_return_t kr = KERN_ABORTED;
+
+  // kernel semaphores take a relative timeout
   mach_timespec_t waitspec;
-  waitspec.tv_sec = sec;
-  waitspec.tv_nsec = nsec;
+  int secs = millis / MILLIUNITS;
+  int nsecs = (millis % MILLIUNITS) * NANOSECS_PER_MILLISEC;
+  waitspec.tv_sec = secs;
+  waitspec.tv_nsec = nsecs;
 
-  int64_t starttime = currenttime();
+  int64_t starttime = os::javaTimeMillis() * NANOSECS_PER_MILLISEC;
 
   kr = semaphore_timedwait(_semaphore, waitspec);
   while (kr == KERN_ABORTED) {
-    int64_t totalwait = (sec * NANOSECS_PER_SEC) + nsec;
-
-    int64_t current = currenttime();
+    // reduce the timout and try again
+    int64_t totalwait = millis * NANOSECS_PER_MILLISEC;
+    int64_t current = os::javaTimeMillis() * NANOSECS_PER_MILLISEC;
     int64_t passedtime = current - starttime;
 
     if (passedtime >= totalwait) {
--- a/src/hotspot/os/bsd/semaphore_bsd.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/bsd/semaphore_bsd.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -50,10 +50,9 @@
   void wait();
 
   bool trywait();
-  bool timedwait(unsigned int sec, int nsec);
 
- private:
-  static int64_t currenttime();
+  // wait until the given relative time elapses
+  bool timedwait(int64_t millis);
 };
 
 typedef OSXSemaphore SemaphoreImpl;
--- a/src/hotspot/os/linux/os_linux.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/linux/os_linux.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -2436,26 +2436,6 @@
   return CAST_FROM_FN_PTR(void*, UserHandler);
 }
 
-static struct timespec create_semaphore_timespec(unsigned int sec, int nsec) {
-  struct timespec ts;
-  // Semaphore's are always associated with CLOCK_REALTIME
-  os::Posix::clock_gettime(CLOCK_REALTIME, &ts);
-  // see os_posix.cpp for discussion on overflow checking
-  if (sec >= MAX_SECS) {
-    ts.tv_sec += MAX_SECS;
-    ts.tv_nsec = 0;
-  } else {
-    ts.tv_sec += sec;
-    ts.tv_nsec += nsec;
-    if (ts.tv_nsec >= NANOSECS_PER_SEC) {
-      ts.tv_nsec -= NANOSECS_PER_SEC;
-      ++ts.tv_sec; // note: this must be <= max_secs
-    }
-  }
-
-  return ts;
-}
-
 extern "C" {
   typedef void (*sa_handler_t)(int);
   typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
@@ -4327,7 +4307,7 @@
 
   // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
   while (true) {
-    if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2 * NANOSECS_PER_MILLISEC))) {
+    if (sr_semaphore.timedwait(2)) {
       break;
     } else {
       // timeout
@@ -4361,7 +4341,7 @@
 
   while (true) {
     if (sr_notify(osthread) == 0) {
-      if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2 * NANOSECS_PER_MILLISEC))) {
+      if (sr_semaphore.timedwait(2)) {
         if (osthread->sr.is_running()) {
           return;
         }
--- a/src/hotspot/os/posix/os_posix.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/posix/os_posix.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -1619,11 +1619,9 @@
   }
 }
 
-
-// Shared pthread_mutex/cond based PlatformEvent implementation.
-// Not currently usable by Solaris.
-
-#ifndef SOLARIS
+// Shared clock/time and other supporting routines for pthread_mutex/cond
+// initialization. This is enabled on Solaris but only some of the clock/time
+// functionality is actually used there.
 
 // Shared condattr object for use with relative timed-waits. Will be associated
 // with CLOCK_MONOTONIC if available to avoid issues with time-of-day changes,
@@ -1661,11 +1659,11 @@
 
 // This means we have clockid_t, clock_gettime et al and CLOCK_MONOTONIC
 
-static int (*_clock_gettime)(clockid_t, struct timespec *);
-static int (*_clock_getres)(clockid_t, struct timespec *);
-static int (*_pthread_condattr_setclock)(pthread_condattr_t *, clockid_t);
+static int (*_clock_gettime)(clockid_t, struct timespec *) = NULL;
+static int (*_clock_getres)(clockid_t, struct timespec *) = NULL;
+static int (*_pthread_condattr_setclock)(pthread_condattr_t *, clockid_t) = NULL;
 
-static bool _use_clock_monotonic_condattr;
+static bool _use_clock_monotonic_condattr = false;
 
 // Exported clock functionality
 
@@ -1707,9 +1705,6 @@
     handle = RTLD_DEFAULT;
   }
 
-  _clock_gettime = NULL;
-  _clock_getres = NULL;
-
   int (*clock_getres_func)(clockid_t, struct timespec*) =
     (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
   int (*clock_gettime_func)(clockid_t, struct timespec*) =
@@ -1736,8 +1731,6 @@
 
   // 2. Check for pthread_condattr_setclock support.
 
-  _pthread_condattr_setclock = NULL;
-
   // libpthread is already loaded.
   int (*condattr_setclock_func)(pthread_condattr_t*, clockid_t) =
     (int (*)(pthread_condattr_t*, clockid_t))dlsym(RTLD_DEFAULT,
@@ -1750,6 +1743,7 @@
 
   pthread_init_common();
 
+#ifndef SOLARIS
   int status;
   if (_pthread_condattr_setclock != NULL && _clock_gettime != NULL) {
     if ((status = _pthread_condattr_setclock(_condAttr, CLOCK_MONOTONIC)) != 0) {
@@ -1763,18 +1757,20 @@
     } else {
       _use_clock_monotonic_condattr = true;
     }
-  } else {
-    _use_clock_monotonic_condattr = false;
   }
+#endif // !SOLARIS
+
 }
 
 void os::Posix::init_2(void) {
+#ifndef SOLARIS
   log_info(os)("Use of CLOCK_MONOTONIC is%s supported",
                (_clock_gettime != NULL ? "" : " not"));
   log_info(os)("Use of pthread_condattr_setclock is%s supported",
                (_pthread_condattr_setclock != NULL ? "" : " not"));
   log_info(os)("Relative timed-wait using pthread_cond_timedwait is associated with %s",
                _use_clock_monotonic_condattr ? "CLOCK_MONOTONIC" : "the default clock");
+#endif // !SOLARIS
 }
 
 #else // !SUPPORTS_CLOCK_MONOTONIC
@@ -1784,30 +1780,25 @@
 }
 
 void os::Posix::init_2(void) {
+#ifndef SOLARIS
   log_info(os)("Use of CLOCK_MONOTONIC is not supported");
   log_info(os)("Use of pthread_condattr_setclock is not supported");
   log_info(os)("Relative timed-wait using pthread_cond_timedwait is associated with the default clock");
+#endif // !SOLARIS
 }
 
 #endif // SUPPORTS_CLOCK_MONOTONIC
 
-os::PlatformEvent::PlatformEvent() {
-  int status = pthread_cond_init(_cond, _condAttr);
-  assert_status(status == 0, status, "cond_init");
-  status = pthread_mutex_init(_mutex, _mutexAttr);
-  assert_status(status == 0, status, "mutex_init");
-  _event   = 0;
-  _nParked = 0;
-}
-
 // Utility to convert the given timeout to an absolute timespec
-// (based on the appropriate clock) to use with pthread_cond_timewait.
+// (based on the appropriate clock) to use with pthread_cond_timewait,
+// and sem_timedwait().
 // The clock queried here must be the clock used to manage the
-// timeout of the condition variable.
+// timeout of the condition variable or semaphore.
 //
 // The passed in timeout value is either a relative time in nanoseconds
 // or an absolute time in milliseconds. A relative timeout will be
-// associated with CLOCK_MONOTONIC if available; otherwise, or if absolute,
+// associated with CLOCK_MONOTONIC if available, unless the real-time clock
+// is explicitly requested; otherwise, or if absolute,
 // the default time-of-day clock will be used.
 
 // Given time is a 64-bit value and the time_t used in the timespec is
@@ -1824,7 +1815,7 @@
 
 // Calculate a new absolute time that is "timeout" nanoseconds from "now".
 // "unit" indicates the unit of "now_part_sec" (may be nanos or micros depending
-// on which clock is being used).
+// on which clock API is being used).
 static void calc_rel_time(timespec* abstime, jlong timeout, jlong now_sec,
                           jlong now_part_sec, jlong unit) {
   time_t max_secs = now_sec + MAX_SECS;
@@ -1849,6 +1840,7 @@
 
 // Unpack the given deadline in milliseconds since the epoch, into the given timespec.
 // The current time in seconds is also passed in to enforce an upper bound as discussed above.
+// This is only used with gettimeofday, when clock_gettime is not available.
 static void unpack_abs_time(timespec* abstime, jlong deadline, jlong now_sec) {
   time_t max_secs = now_sec + MAX_SECS;
 
@@ -1865,7 +1857,18 @@
   }
 }
 
-static void to_abstime(timespec* abstime, jlong timeout, bool isAbsolute) {
+static jlong millis_to_nanos(jlong millis) {
+  // We have to watch for overflow when converting millis to nanos,
+  // but if millis is that large then we will end up limiting to
+  // MAX_SECS anyway, so just do that here.
+  if (millis / MILLIUNITS > MAX_SECS) {
+    millis = jlong(MAX_SECS) * MILLIUNITS;
+  }
+  return millis * (NANOUNITS / MILLIUNITS);
+}
+
+static void to_abstime(timespec* abstime, jlong timeout,
+                       bool isAbsolute, bool isRealtime) {
   DEBUG_ONLY(int max_secs = MAX_SECS;)
 
   if (timeout < 0) {
@@ -1874,9 +1877,14 @@
 
 #ifdef SUPPORTS_CLOCK_MONOTONIC
 
-  if (_use_clock_monotonic_condattr && !isAbsolute) {
+  clockid_t clock = CLOCK_MONOTONIC;
+  // need to ensure we have a runtime check for clock_gettime support
+  if (!isAbsolute && _clock_gettime != NULL) {
+    if (!_use_clock_monotonic_condattr || isRealtime) {
+      clock = CLOCK_REALTIME;
+    }
     struct timespec now;
-    int status = _clock_gettime(CLOCK_MONOTONIC, &now);
+    int status = _clock_gettime(clock, &now);
     assert_status(status == 0, status, "clock_gettime");
     calc_rel_time(abstime, timeout, now.tv_sec, now.tv_nsec, NANOUNITS);
     DEBUG_ONLY(max_secs += now.tv_sec;)
@@ -1906,6 +1914,19 @@
   assert(abstime->tv_nsec < NANOUNITS, "tv_nsec >= NANOUNITS");
 }
 
+// Create an absolute time 'millis' milliseconds in the future, using the
+// real-time (time-of-day) clock. Used by PosixSemaphore.
+void os::Posix::to_RTC_abstime(timespec* abstime, int64_t millis) {
+  to_abstime(abstime, millis_to_nanos(millis),
+             false /* not absolute */,
+             true  /* use real-time clock */);
+}
+
+// Shared pthread_mutex/cond based PlatformEvent implementation.
+// Not currently usable by Solaris.
+
+#ifndef SOLARIS
+
 // PlatformEvent
 //
 // Assumption:
@@ -1921,6 +1942,15 @@
 //    Having three states allows for some detection of bad usage - see
 //    comments on unpark().
 
+os::PlatformEvent::PlatformEvent() {
+  int status = pthread_cond_init(_cond, _condAttr);
+  assert_status(status == 0, status, "cond_init");
+  status = pthread_mutex_init(_mutex, _mutexAttr);
+  assert_status(status == 0, status, "mutex_init");
+  _event   = 0;
+  _nParked = 0;
+}
+
 void os::PlatformEvent::park() {       // AKA "down()"
   // Transitions for _event:
   //   -1 => -1 : illegal
@@ -1982,13 +2012,7 @@
 
   if (v == 0) { // Do this the hard way by blocking ...
     struct timespec abst;
-    // We have to watch for overflow when converting millis to nanos,
-    // but if millis is that large then we will end up limiting to
-    // MAX_SECS anyway, so just do that here.
-    if (millis / MILLIUNITS > MAX_SECS) {
-      millis = jlong(MAX_SECS) * MILLIUNITS;
-    }
-    to_abstime(&abst, millis * (NANOUNITS / MILLIUNITS), false);
+    to_abstime(&abst, millis_to_nanos(millis), false, false);
 
     int ret = OS_TIMEOUT;
     int status = pthread_mutex_lock(_mutex);
@@ -2106,7 +2130,7 @@
     return;
   }
   if (time > 0) {
-    to_abstime(&absTime, time, isAbsolute);
+    to_abstime(&absTime, time, isAbsolute, false);
   }
 
   // Enter safepoint region
--- a/src/hotspot/os/posix/os_posix.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/posix/os_posix.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -132,6 +132,8 @@
   static bool supports_monotonic_clock() { return false; }
 
 #endif
+
+  static void to_RTC_abstime(timespec* abstime, int64_t millis);
 };
 
 /*
--- a/src/hotspot/os/posix/semaphore_posix.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/posix/semaphore_posix.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -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
@@ -79,6 +79,12 @@
   return ret == 0;
 }
 
+bool PosixSemaphore::timedwait(int64_t millis) {
+  struct timespec ts;
+  os::Posix::to_RTC_abstime(&ts, millis);
+  return timedwait(ts);
+}
+
 bool PosixSemaphore::timedwait(struct timespec ts) {
   while (true) {
     int result = sem_timedwait(&_semaphore, &ts);
--- a/src/hotspot/os/posix/semaphore_posix.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/posix/semaphore_posix.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -45,7 +45,10 @@
   void wait();
 
   bool trywait();
+  // wait until the given absolute time is reached
   bool timedwait(struct timespec ts);
+  // wait until the given relative time elapses
+  bool timedwait(int64_t millis);
 };
 
 typedef PosixSemaphore SemaphoreImpl;
--- a/src/hotspot/os/solaris/os_solaris.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -2011,13 +2011,6 @@
   return CAST_FROM_FN_PTR(void*, UserHandler);
 }
 
-static struct timespec create_semaphore_timespec(unsigned int sec, int nsec) {
-  struct timespec ts;
-  unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
-
-  return ts;
-}
-
 extern "C" {
   typedef void (*sa_handler_t)(int);
   typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
@@ -3493,7 +3486,7 @@
 
   // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
   while (true) {
-    if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2000 * NANOSECS_PER_MILLISEC))) {
+    if (sr_semaphore.timedwait(2000)) {
       break;
     } else {
       // timeout
@@ -3527,7 +3520,7 @@
 
   while (true) {
     if (sr_notify(osthread) == 0) {
-      if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2 * NANOSECS_PER_MILLISEC))) {
+      if (sr_semaphore.timedwait(2)) {
         if (osthread->sr.is_running()) {
           return;
         }
@@ -4112,6 +4105,9 @@
     Solaris::_pthread_setname_np =  // from 11.3
         (Solaris::pthread_setname_np_func_t)dlsym(handle, "pthread_setname_np");
   }
+
+  // Shared Posix initialization
+  os::Posix::init();
 }
 
 // To install functions for atexit system call
@@ -4218,6 +4214,9 @@
   // Init pset_loadavg function pointer
   init_pset_getloadavg_ptr();
 
+  // Shared Posix initialization
+  os::Posix::init_2();
+
   return JNI_OK;
 }
 
--- a/src/hotspot/share/ci/ciEnv.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/ci/ciEnv.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -915,8 +915,15 @@
   return JavaThread::current()->thread_state() == _thread_in_vm;
 }
 
+bool ciEnv::system_dictionary_modification_counter_changed_locked() {
+  assert_locked_or_safepoint(Compile_lock);
+  return _system_dictionary_modification_counter != SystemDictionary::number_of_modifications();
+}
+
 bool ciEnv::system_dictionary_modification_counter_changed() {
-  return _system_dictionary_modification_counter != SystemDictionary::number_of_modifications();
+  VM_ENTRY_MARK;
+  MutexLocker ml(Compile_lock, THREAD); // lock with safepoint check
+  return system_dictionary_modification_counter_changed_locked();
 }
 
 // ------------------------------------------------------------------
@@ -927,7 +934,7 @@
 void ciEnv::validate_compile_task_dependencies(ciMethod* target) {
   if (failing())  return;  // no need for further checks
 
-  bool counter_changed = system_dictionary_modification_counter_changed();
+  bool counter_changed = system_dictionary_modification_counter_changed_locked();
   Dependencies::DepType result = dependencies()->validate_dependencies(_task, counter_changed);
   if (result != Dependencies::end_marker) {
     if (result == Dependencies::call_site_target_value) {
--- a/src/hotspot/share/ci/ciEnv.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/ci/ciEnv.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -292,6 +292,8 @@
   // respect to method dependencies (e.g. concurrent class loading).
   void validate_compile_task_dependencies(ciMethod* target);
 
+  // Call internally when Compile_lock is already held.
+  bool system_dictionary_modification_counter_changed_locked();
 public:
   enum {
     MethodCompilable,
--- a/src/hotspot/share/classfile/classLoader.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/classfile/classLoader.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -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
@@ -1724,7 +1724,7 @@
 
   {
     MutexLocker ml(Module_lock, THREAD);
-    ModuleEntry* jb_module = null_cld_modules->locked_create_entry_or_null(Handle(),
+    ModuleEntry* jb_module = null_cld_modules->locked_create_entry(Handle(),
                                false, vmSymbols::java_base(), NULL, NULL, null_cld);
     if (jb_module == NULL) {
       vm_exit_during_initialization("Unable to create ModuleEntry for " JAVA_BASE_NAME);
--- a/src/hotspot/share/classfile/moduleEntry.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/classfile/moduleEntry.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -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
@@ -398,23 +398,22 @@
   Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry);
 }
 
-ModuleEntry* ModuleEntryTable::locked_create_entry_or_null(Handle module_handle,
-                                                           bool is_open,
-                                                           Symbol* module_name,
-                                                           Symbol* module_version,
-                                                           Symbol* module_location,
-                                                           ClassLoaderData* loader_data) {
-  assert(module_name != NULL, "ModuleEntryTable locked_create_entry_or_null should never be called for unnamed module.");
+// Create an entry in the class loader's module_entry_table.  It is the
+// caller's responsibility to ensure that the entry has not already been
+// created.
+ModuleEntry* ModuleEntryTable::locked_create_entry(Handle module_handle,
+                                                   bool is_open,
+                                                   Symbol* module_name,
+                                                   Symbol* module_version,
+                                                   Symbol* module_location,
+                                                   ClassLoaderData* loader_data) {
+  assert(module_name != NULL, "ModuleEntryTable locked_create_entry should never be called for unnamed module.");
   assert(Module_lock->owned_by_self(), "should have the Module_lock");
-  // Check if module already exists.
-  if (lookup_only(module_name) != NULL) {
-    return NULL;
-  } else {
-    ModuleEntry* entry = new_entry(compute_hash(module_name), module_handle, is_open, module_name,
-                                   module_version, module_location, loader_data);
-    add_entry(index_for(module_name), entry);
-    return entry;
-  }
+  assert(lookup_only(module_name) == NULL, "Module already exists");
+  ModuleEntry* entry = new_entry(compute_hash(module_name), module_handle, is_open, module_name,
+                                 module_version, module_location, loader_data);
+  add_entry(index_for(module_name), entry);
+  return entry;
 }
 
 // lookup_only by Symbol* to find a ModuleEntry.
--- a/src/hotspot/share/classfile/moduleEntry.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/classfile/moduleEntry.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -236,14 +236,14 @@
     return (ModuleEntry*)Hashtable<Symbol*, mtModule>::bucket(i);
   }
 
-  // Create module in loader's module entry table, if already exists then
-  // return null.  Assume Module_lock has been locked by caller.
-  ModuleEntry* locked_create_entry_or_null(Handle module_handle,
-                                           bool is_open,
-                                           Symbol* module_name,
-                                           Symbol* module_version,
-                                           Symbol* module_location,
-                                           ClassLoaderData* loader_data);
+  // Create module in loader's module entry table.  Assume Module_lock
+  // has been locked by caller.
+  ModuleEntry* locked_create_entry(Handle module_handle,
+                                   bool is_open,
+                                   Symbol* module_name,
+                                   Symbol* module_version,
+                                   Symbol* module_location,
+                                   ClassLoaderData* loader_data);
 
   // Only lookup module within loader's module entry table.  The table read is lock-free.
   ModuleEntry* lookup_only(Symbol* name);
@@ -253,7 +253,10 @@
 
   // Special handling for java.base
   static ModuleEntry* javabase_moduleEntry()                   { return _javabase_module; }
-  static void set_javabase_moduleEntry(ModuleEntry* java_base) { _javabase_module = java_base; }
+  static void set_javabase_moduleEntry(ModuleEntry* java_base) {
+    assert(_javabase_module == NULL, "_javabase_module is already defined");
+    _javabase_module = java_base;
+  }
 
   static bool javabase_defined() { return ((_javabase_module != NULL) &&
                                            (_javabase_module->module() != NULL)); }
--- a/src/hotspot/share/classfile/modules.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/classfile/modules.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -208,10 +208,9 @@
       // loop through and add any new packages for java.base
       for (int x = 0; x < pkg_list->length(); x++) {
         // Some of java.base's packages were added early in bootstrapping, ignore duplicates.
-        PackageEntry* pkg =
-          package_table->locked_create_entry_or_null(pkg_list->at(x),
-                                                     ModuleEntryTable::javabase_moduleEntry());
-        assert(pkg != NULL || package_table->locked_lookup_only(pkg_list->at(x)) != NULL,
+        package_table->locked_create_entry_if_not_exist(pkg_list->at(x),
+                                                        ModuleEntryTable::javabase_moduleEntry());
+        assert(package_table->locked_lookup_only(pkg_list->at(x)) != NULL,
                "Unable to create a " JAVA_BASE_NAME " package entry");
         // Unable to have a GrowableArray of TempNewSymbol.  Must decrement the refcount of
         // the Symbol* that was created above for each package. The refcount was incremented
@@ -402,20 +401,17 @@
 
     // Add the module and its packages.
     if (!dupl_modules && existing_pkg == NULL) {
-      // Create the entry for this module in the class loader's module entry table.
-      ModuleEntry* module_entry = module_table->locked_create_entry_or_null(module_handle,
+      if (module_table->lookup_only(module_symbol) == NULL) {
+        // Create the entry for this module in the class loader's module entry table.
+        ModuleEntry* module_entry = module_table->locked_create_entry(module_handle,
                                     (is_open == JNI_TRUE), module_symbol,
                                     version_symbol, location_symbol, loader_data);
+        assert(module_entry != NULL, "module_entry creation failed");
 
-      if (module_entry == NULL) {
-        dupl_modules = true;
-      } else {
         // Add the packages.
         assert(pkg_list->length() == 0 || package_table != NULL, "Bad package table");
-        PackageEntry* pkg;
         for (int y = 0; y < pkg_list->length(); y++) {
-          pkg = package_table->locked_create_entry_or_null(pkg_list->at(y), module_entry);
-          assert(pkg != NULL, "Unable to create a module's package entry");
+          package_table->locked_create_entry(pkg_list->at(y), module_entry);
 
           // Unable to have a GrowableArray of TempNewSymbol.  Must decrement the refcount of
           // the Symbol* that was created above for each package. The refcount was incremented
@@ -425,6 +421,8 @@
 
         // Store pointer to ModuleEntry record in java.lang.Module object.
         java_lang_Module::set_module_entry(module_handle(), module_entry);
+      } else {
+         dupl_modules = true;
       }
     }
   }  // Release the lock
--- a/src/hotspot/share/classfile/packageEntry.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/classfile/packageEntry.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -211,17 +211,22 @@
   Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry);
 }
 
-// Create package in loader's package entry table and return the entry.
-// If entry already exists, return null.  Assume Module lock was taken by caller.
-PackageEntry* PackageEntryTable::locked_create_entry_or_null(Symbol* name, ModuleEntry* module) {
+// Create package entry in loader's package entry table.  Assume Module lock
+// was taken by caller.
+void PackageEntryTable::locked_create_entry(Symbol* name, ModuleEntry* module) {
   assert(Module_lock->owned_by_self(), "should have the Module_lock");
-  // Check if package already exists.  Return NULL if it does.
-  if (locked_lookup_only(name) != NULL) {
-    return NULL;
-  } else {
-    PackageEntry* entry = new_entry(compute_hash(name), name, module);
-    add_entry(index_for(name), entry);
-    return entry;
+  assert(locked_lookup_only(name) == NULL, "Package entry already exists");
+  PackageEntry* entry = new_entry(compute_hash(name), name, module);
+  add_entry(index_for(name), entry);
+}
+
+// Create package entry in loader's package entry table if it does not already
+// exist.  Assume Module lock was taken by caller.
+void PackageEntryTable::locked_create_entry_if_not_exist(Symbol* name, ModuleEntry* module) {
+  assert(Module_lock->owned_by_self(), "should have the Module_lock");
+  // Check if package entry already exists.  If not, create it.
+  if (locked_lookup_only(name) == NULL) {
+    locked_create_entry(name, module);
   }
 }
 
--- a/src/hotspot/share/classfile/packageEntry.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/classfile/packageEntry.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -246,9 +246,13 @@
     return (PackageEntry*)Hashtable<Symbol*, mtModule>::bucket(i);
   }
 
-  // Create package in loader's package entry table and return the entry.
-  // If entry already exists, return null.  Assume Module lock was taken by caller.
-  PackageEntry* locked_create_entry_or_null(Symbol* name, ModuleEntry* module);
+  // Create package entry in loader's package entry table.  Assume Module
+  // lock was taken by caller.
+  void locked_create_entry(Symbol* name, ModuleEntry* module);
+
+  // Create package entry in loader's package entry table if it does not
+  // already exist.  Assume Module lock was taken by caller.
+  void locked_create_entry_if_not_exist(Symbol* name, ModuleEntry* module);
 
   // Lookup Package with loader's package entry table, add it if not found.
   // This will acquire the Module lock.
--- a/src/hotspot/share/libadt/vectset.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/libadt/vectset.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -110,7 +110,6 @@
 
   // Expose internals for speed-critical fast iterators
   uint word_size() const { return size; }
-  uint32_t* EXPOSE() const { return data; }
 
   // Fast inlined "test and set".  Replaces the idiom:
   //     if( visited[idx] ) return;
--- a/src/hotspot/share/opto/callGenerator.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/opto/callGenerator.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, 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
@@ -90,7 +90,6 @@
   // Grab signature for matching/allocation
 #ifdef ASSERT
   if (parser.tf() != (parser.depth() == 1 ? C->tf() : tf())) {
-    MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag);
     assert(C->env()->system_dictionary_modification_counter_changed(),
            "Must invalidate if TypeFuncs differ");
   }
--- a/src/hotspot/share/opto/chaitin.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/opto/chaitin.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -749,6 +749,17 @@
       LRG& lrg = lrgs(vreg);
       if (vreg) {              // No vreg means un-allocable (e.g. memory)
 
+        // Check for float-vs-int live range (used in register-pressure
+        // calculations)
+        const Type *n_type = n->bottom_type();
+        if (n_type->is_floatingpoint()) {
+          lrg._is_float = 1;
+        }
+
+#ifndef PRODUCT
+        // Collect bits not used by product code, but which may be useful for
+        // debugging.
+
         // Collect has-copy bit
         if (idx) {
           lrg._has_copy = 1;
@@ -757,13 +768,6 @@
           copy_src._has_copy = 1;
         }
 
-        // Check for float-vs-int live range (used in register-pressure
-        // calculations)
-        const Type *n_type = n->bottom_type();
-        if (n_type->is_floatingpoint()) {
-          lrg._is_float = 1;
-        }
-
         // Check for twice prior spilling.  Once prior spilling might have
         // spilled 'soft', 2nd prior spill should have spilled 'hard' and
         // further spilling is unlikely to make progress.
@@ -774,7 +778,6 @@
           }
         }
 
-#ifndef PRODUCT
         if (trace_spilling() && lrg._def != NULL) {
           // collect defs for MultiDef printing
           if (lrg._defs == NULL) {
@@ -1109,8 +1112,6 @@
 #endif
 }
 
-#define REGISTER_CONSTRAINED 16
-
 // Compute cost/area ratio, in case we spill.  Build the lo-degree list.
 void PhaseChaitin::cache_lrg_info( ) {
   Compile::TracePhase tp("chaitinCacheLRG", &timers[_t_chaitinCacheLRG]);
@@ -1145,56 +1146,6 @@
   }
 }
 
-// Simplify the IFG by removing LRGs of low degree that have NO copies
-void PhaseChaitin::Pre_Simplify( ) {
-
-  // Warm up the lo-degree no-copy list
-  int lo_no_copy = 0;
-  for (uint i = 1; i < _lrg_map.max_lrg_id(); i++) {
-    if ((lrgs(i).lo_degree() && !lrgs(i)._has_copy) ||
-        !lrgs(i).alive() ||
-        lrgs(i)._must_spill) {
-      lrgs(i)._next = lo_no_copy;
-      lo_no_copy = i;
-    }
-  }
-
-  while( lo_no_copy ) {
-    uint lo = lo_no_copy;
-    lo_no_copy = lrgs(lo)._next;
-    int size = lrgs(lo).num_regs();
-
-    // Put the simplified guy on the simplified list.
-    lrgs(lo)._next = _simplified;
-    _simplified = lo;
-
-    // Yank this guy from the IFG.
-    IndexSet *adj = _ifg->remove_node( lo );
-
-    // If any neighbors' degrees fall below their number of
-    // allowed registers, then put that neighbor on the low degree
-    // list.  Note that 'degree' can only fall and 'numregs' is
-    // unchanged by this action.  Thus the two are equal at most once,
-    // so LRGs hit the lo-degree worklists at most once.
-    IndexSetIterator elements(adj);
-    uint neighbor;
-    while ((neighbor = elements.next()) != 0) {
-      LRG *n = &lrgs(neighbor);
-      assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
-
-      // Check for just becoming of-low-degree
-      if( n->just_lo_degree() && !n->_has_copy ) {
-        assert(!(*_ifg->_yanked)[neighbor],"Cannot move to lo degree twice");
-        // Put on lo-degree list
-        n->_next = lo_no_copy;
-        lo_no_copy = neighbor;
-      }
-    }
-  } // End of while lo-degree no_copy worklist not empty
-
-  // No more lo-degree no-copy live ranges to simplify
-}
-
 // Simplify the IFG by removing LRGs of low degree.
 void PhaseChaitin::Simplify( ) {
   Compile::TracePhase tp("chaitinSimplify", &timers[_t_chaitinSimplify]);
@@ -1616,18 +1567,6 @@
   return spill_reg-LRG::SPILL_REG;      // Return number of spills
 }
 
-// Copy 'was_spilled'-edness from the source Node to the dst Node.
-void PhaseChaitin::copy_was_spilled( Node *src, Node *dst ) {
-  if( _spilled_once.test(src->_idx) ) {
-    _spilled_once.set(dst->_idx);
-    lrgs(_lrg_map.find(dst))._was_spilled1 = 1;
-    if( _spilled_twice.test(src->_idx) ) {
-      _spilled_twice.set(dst->_idx);
-      lrgs(_lrg_map.find(dst))._was_spilled2 = 1;
-    }
-  }
-}
-
 // Set the 'spilled_once' or 'spilled_twice' flag on a node.
 void PhaseChaitin::set_was_spilled( Node *n ) {
   if( _spilled_once.test_set(n->_idx) )
--- a/src/hotspot/share/opto/chaitin.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/opto/chaitin.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -35,12 +35,11 @@
 #include "opto/regmask.hpp"
 #include "opto/machnode.hpp"
 
-class LoopTree;
 class Matcher;
 class PhaseCFG;
 class PhaseLive;
 class PhaseRegAlloc;
-class   PhaseChaitin;
+class PhaseChaitin;
 
 #define OPTO_DEBUG_SPLIT_FREQ  BLOCK_FREQUENCY(0.001)
 #define OPTO_LRG_HIGH_FREQ     BLOCK_FREQUENCY(0.25)
@@ -136,7 +135,6 @@
 
   void Insert( OptoReg::Name reg ) { _mask.Insert(reg);  debug_only(_msize_valid=0;) }
   void Remove( OptoReg::Name reg ) { _mask.Remove(reg);  debug_only(_msize_valid=0;) }
-  void clear_to_pairs() { _mask.clear_to_pairs(); debug_only(_msize_valid=0;) }
   void clear_to_sets()  { _mask.clear_to_sets(_num_regs); debug_only(_msize_valid=0;) }
 
   // Number of registers this live range uses when it colors
@@ -237,9 +235,6 @@
   // Add edge between a and b.  Returns true if actually addded.
   int add_edge( uint a, uint b );
 
-  // Add edge between a and everything in the vector
-  void add_vector( uint a, IndexSet *vec );
-
   // Test for edge existance
   int test_edge( uint a, uint b ) const;
 
@@ -401,7 +396,6 @@
 
   PhaseLive *_live;             // Liveness, used in the interference graph
   PhaseIFG *_ifg;               // Interference graph (for original chunk)
-  Node_List **_lrg_nodes;       // Array of node; lists for lrgs which spill
   VectorSet _spilled_once;      // Nodes that have been spilled
   VectorSet _spilled_twice;     // Nodes that have been spilled twice
 
@@ -496,8 +490,7 @@
   void de_ssa();
 
   // Add edge between reg and everything in the vector.
-  // Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask
-  // information to trim the set of interferences.  Return the
+  // Use the RegMask information to trim the set of interferences.  Return the
   // count of edges added.
   void interfere_with_live(uint lid, IndexSet* liveout);
 #ifdef ASSERT
@@ -666,17 +659,9 @@
   // coalescing, it should Simplify.  This call sets the was-lo-degree bit.
   void set_was_low();
 
-  // Split live-ranges that must spill due to register conflicts (as opposed
-  // to capacity spills).  Typically these are things def'd in a register
-  // and used on the stack or vice-versa.
-  void pre_spill();
-
   // Init LRG caching of degree, numregs.  Init lo_degree list.
   void cache_lrg_info( );
 
-  // Simplify the IFG by removing LRGs of low degree with no copies
-  void Pre_Simplify();
-
   // Simplify the IFG by removing LRGs of low degree
   void Simplify();
 
@@ -692,8 +677,6 @@
   // Return new number of live ranges
   uint Split(uint maxlrg, ResourceArea* split_arena);
 
-  // Copy 'was_spilled'-edness from one Node to another.
-  void copy_was_spilled( Node *src, Node *dst );
   // Set the 'spilled_once' or 'spilled_twice' flag on a node.
   void set_was_spilled( Node *n );
 
--- a/src/hotspot/share/opto/ifg.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/opto/ifg.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -67,20 +67,6 @@
   return _adjs[a].insert( b );
 }
 
-// Add an edge between 'a' and everything in the vector.
-void PhaseIFG::add_vector( uint a, IndexSet *vec ) {
-  // IFG is triangular, so do the inserts where 'a' < 'b'.
-  assert( !_is_square, "only on triangular" );
-  IndexSet *adjs_a = &_adjs[a];
-  if( !vec->count() ) return;
-
-  IndexSetIterator elements(vec);
-  uint neighbor;
-  while ((neighbor = elements.next()) != 0) {
-    add_edge( a, neighbor );
-  }
-}
-
 // Is there an edge between a and b?
 int PhaseIFG::test_edge( uint a, uint b ) const {
   // Sort a and b, so that a is larger
--- a/src/hotspot/share/opto/parse1.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/opto/parse1.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -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
@@ -524,7 +524,6 @@
   if (depth() == 1) {
     assert(C->is_osr_compilation() == this->is_osr_parse(), "OSR in sync");
     if (C->tf() != tf()) {
-      MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag);
       assert(C->env()->system_dictionary_modification_counter_changed(),
              "Must invalidate if TypeFuncs differ");
     }
@@ -1041,7 +1040,6 @@
       // not compilable. Just using an assertion instead would be dangerous
       // as this could lead to an infinite compile loop in non-debug builds.
       {
-        MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag);
         if (C->env()->system_dictionary_modification_counter_changed()) {
           C->record_failure(C2Compiler::retry_class_loading_during_parsing());
         } else {
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -306,7 +306,7 @@
   def(JvmtiThreadState_lock        , PaddedMutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // Used by JvmtiThreadState/JvmtiEventController
   def(Management_lock              , PaddedMutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // used for JVM management
 
-  def(Compile_lock                 , PaddedMutex  , nonleaf+3,   true,  Monitor::_safepoint_check_sometimes);
+  def(Compile_lock                 , PaddedMutex  , nonleaf+3,   true,  Monitor::_safepoint_check_always);
   def(MethodData_lock              , PaddedMutex  , nonleaf+3,   false, Monitor::_safepoint_check_always);
   def(TouchedMethodLog_lock        , PaddedMutex  , nonleaf+3,   false, Monitor::_safepoint_check_always);
 
--- a/src/hotspot/share/runtime/vmOperations.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/runtime/vmOperations.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -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
@@ -333,8 +333,7 @@
       if (_with_locked_synchronizers) {
         tcl = concurrent_locks.thread_concurrent_locks(jt);
       }
-      ThreadSnapshot* ts = snapshot_thread(jt, tcl);
-      _result->add_thread_snapshot(ts);
+      snapshot_thread(jt, tcl);
     }
   } else {
     // Snapshot threads in the given _threads array
@@ -345,7 +344,7 @@
       if (th() == NULL) {
         // skip if the thread doesn't exist
         // Add a dummy snapshot
-        _result->add_thread_snapshot(new ThreadSnapshot());
+        _result->add_thread_snapshot();
         continue;
       }
 
@@ -362,24 +361,22 @@
           jt->is_exiting() ||
           jt->is_hidden_from_external_view())  {
         // add a NULL snapshot if skipped
-        _result->add_thread_snapshot(new ThreadSnapshot());
+        _result->add_thread_snapshot();
         continue;
       }
       ThreadConcurrentLocks* tcl = NULL;
       if (_with_locked_synchronizers) {
         tcl = concurrent_locks.thread_concurrent_locks(jt);
       }
-      ThreadSnapshot* ts = snapshot_thread(jt, tcl);
-      _result->add_thread_snapshot(ts);
+      snapshot_thread(jt, tcl);
     }
   }
 }
 
-ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) {
-  ThreadSnapshot* snapshot = new ThreadSnapshot(_result->t_list(), java_thread);
+void VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) {
+  ThreadSnapshot* snapshot = _result->add_thread_snapshot(java_thread);
   snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors);
   snapshot->set_concurrent_locks(tcl);
-  return snapshot;
 }
 
 volatile bool VM_Exit::_vm_exited = false;
--- a/src/hotspot/share/runtime/vmOperations.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/runtime/vmOperations.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -445,7 +445,7 @@
   bool                           _with_locked_monitors;
   bool                           _with_locked_synchronizers;
 
-  ThreadSnapshot* snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl);
+  void snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl);
 
  public:
   VM_ThreadDump(ThreadDumpResult* result,
--- a/src/hotspot/share/services/management.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/services/management.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, 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
@@ -1097,15 +1097,13 @@
     for (int i = 0; i < num_threads; i++) {
       jlong tid = ids_ah->long_at(i);
       JavaThread* jt = dump_result.t_list()->find_JavaThread_from_java_tid(tid);
-      ThreadSnapshot* ts;
       if (jt == NULL) {
         // if the thread does not exist or now it is terminated,
         // create dummy snapshot
-        ts = new ThreadSnapshot();
+        dump_result.add_thread_snapshot();
       } else {
-        ts = new ThreadSnapshot(dump_result.t_list(), jt);
+        dump_result.add_thread_snapshot(jt);
       }
-      dump_result.add_thread_snapshot(ts);
     }
   } else {
     // obtain thread dump with the specific list of threads with stack trace
--- a/src/hotspot/share/services/threadService.cpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/services/threadService.cpp	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, 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
@@ -503,8 +503,25 @@
   }
 }
 
+ThreadSnapshot* ThreadDumpResult::add_thread_snapshot() {
+  ThreadSnapshot* ts = new ThreadSnapshot();
+  link_thread_snapshot(ts);
+  return ts;
+}
 
-void ThreadDumpResult::add_thread_snapshot(ThreadSnapshot* ts) {
+ThreadSnapshot* ThreadDumpResult::add_thread_snapshot(JavaThread* thread) {
+  // Note: it is very important that the ThreadSnapshot* gets linked before
+  // ThreadSnapshot::initialize gets called. This is to ensure that
+  // ThreadSnapshot::oops_do can get called prior to the field
+  // ThreadSnapshot::_threadObj being assigned a value (to prevent a dangling
+  // oop).
+  ThreadSnapshot* ts = new ThreadSnapshot();
+  link_thread_snapshot(ts);
+  ts->initialize(t_list(), thread);
+  return ts;
+}
+
+void ThreadDumpResult::link_thread_snapshot(ThreadSnapshot* ts) {
   assert(_num_threads == 0 || _num_snapshots < _num_threads,
          "_num_snapshots must be less than _num_threads");
   _num_snapshots++;
@@ -831,12 +848,9 @@
   memset((void*) _perf_recursion_counts, 0, sizeof(_perf_recursion_counts));
 }
 
-ThreadSnapshot::ThreadSnapshot(ThreadsList * t_list, JavaThread* thread) {
+void ThreadSnapshot::initialize(ThreadsList * t_list, JavaThread* thread) {
   _thread = thread;
   _threadObj = thread->threadObj();
-  _stack_trace = NULL;
-  _concurrent_locks = NULL;
-  _next = NULL;
 
   ThreadStatistics* stat = thread->get_thread_stat();
   _contended_enter_ticks = stat->contended_enter_ticks();
@@ -846,9 +860,6 @@
   _sleep_ticks = stat->sleep_ticks();
   _sleep_count = stat->sleep_count();
 
-  _blocker_object = NULL;
-  _blocker_object_owner = NULL;
-
   _thread_status = java_lang_Thread::get_thread_status(_threadObj);
   _is_ext_suspended = thread->is_being_ext_suspended();
   _is_in_native = (thread->thread_state() == _thread_in_native);
--- a/src/hotspot/share/services/threadService.hpp	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/hotspot/share/services/threadService.hpp	Thu Jan 24 17:29:21 2019 +0000
@@ -213,12 +213,15 @@
   ThreadConcurrentLocks* _concurrent_locks;
   ThreadSnapshot*        _next;
 
-public:
-  // Dummy snapshot
+  // ThreadSnapshot instances should only be created via
+  // ThreadDumpResult::add_thread_snapshot.
+  friend class ThreadDumpResult;
   ThreadSnapshot() : _thread(NULL), _threadObj(NULL),
                      _blocker_object(NULL), _blocker_object_owner(NULL),
                      _stack_trace(NULL), _concurrent_locks(NULL), _next(NULL) {};
-  ThreadSnapshot(ThreadsList * t_list, JavaThread* thread);
+  void        initialize(ThreadsList * t_list, JavaThread* thread);
+
+public:
   ~ThreadSnapshot();
 
   java_lang_Thread::ThreadStatus thread_status() { return _thread_status; }
@@ -367,12 +370,16 @@
   ThreadsListSetter    _setter;  // Helper to set hazard ptr in the originating thread
                                  // which protects the JavaThreads in _snapshots.
 
+  void                 link_thread_snapshot(ThreadSnapshot* ts);
+
  public:
   ThreadDumpResult();
   ThreadDumpResult(int num_threads);
   ~ThreadDumpResult();
 
-  void                 add_thread_snapshot(ThreadSnapshot* ts);
+  ThreadSnapshot*      add_thread_snapshot();
+  ThreadSnapshot*      add_thread_snapshot(JavaThread* thread);
+
   void                 set_next(ThreadDumpResult* next) { _next = next; }
   ThreadDumpResult*    next()                           { return _next; }
   int                  num_threads()                    { return _num_threads; }
--- a/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java	Thu Jan 24 17:29:21 2019 +0000
@@ -171,9 +171,8 @@
         URL destURL = new URL(urlString);
         HttpURLConnection conn = (HttpURLConnection) destURL.openConnection(proxy);
         conn.setConnectTimeout(connectTimeout);
-        Object value = getOption(SocketOptions.SO_TIMEOUT);
-        if (value != null) {
-            Integer timeout = (Integer) value;
+        int timeout = (int) getOption(SocketOptions.SO_TIMEOUT);
+        if (timeout > 0) {
             conn.setReadTimeout(timeout);
         }
         conn.connect();
--- a/src/java.base/share/classes/java/net/SocksSocketImpl.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java	Thu Jan 24 17:29:21 2019 +0000
@@ -23,20 +23,18 @@
  * questions.
  */
 package java.net;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.BufferedOutputStream;
 import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
 
 import jdk.internal.util.StaticProperty;
 import sun.net.SocksProxy;
 import sun.net.spi.DefaultProxySelector;
 import sun.net.www.ParseUtil;
 import sun.nio.ch.NioSocketImpl;
-/* import org.ietf.jgss.*; */
 
 /**
  * SOCKS (V4 & V5) TCP socket implementation (RFC 1928).
@@ -51,8 +49,6 @@
     private Socket cmdsock = null;
     private InputStream cmdIn = null;
     private OutputStream cmdOut = null;
-    /* true if the Proxy has been set programmatically */
-    private boolean applicationSetProxy;  /* false */
 
     SocksSocketImpl() {
         super(false);
@@ -70,10 +66,6 @@
         useV4 = useV4(proxy);
     }
 
-    void setV4() {
-        useV4 = true;
-    }
-
     private static boolean useV4(Proxy proxy) {
         if (proxy instanceof SocksProxy
             && ((SocksProxy)proxy).protocolVersion() == 4) {
@@ -118,10 +110,6 @@
         throw new SocketTimeoutException();
     }
 
-    private int readSocksReply(InputStream in, byte[] data) throws IOException {
-        return readSocksReply(in, data, 0L);
-    }
-
     private int readSocksReply(InputStream in, byte[] data, long deadlineMillis) throws IOException {
         int len = data.length;
         int received = 0;
@@ -146,14 +134,6 @@
         return received;
     }
 
-    /**
-     * Provides the authentication mechanism required by the proxy.
-     */
-    private boolean authenticate(byte method, InputStream in,
-                                 BufferedOutputStream out) throws IOException {
-        return authenticate(method, in, out, 0L);
-    }
-
     private boolean authenticate(byte method, InputStream in,
                                  BufferedOutputStream out,
                                  long deadlineMillis) throws IOException {
@@ -214,60 +194,6 @@
             /* Authentication succeeded */
             return true;
         }
-        /**
-         * GSSAPI authentication mechanism.
-         * Unfortunately the RFC seems out of sync with the Reference
-         * implementation. I'll leave this in for future completion.
-         */
-//      if (method == GSSAPI) {
-//          try {
-//              GSSManager manager = GSSManager.getInstance();
-//              GSSName name = manager.createName("SERVICE:socks@"+server,
-//                                                   null);
-//              GSSContext context = manager.createContext(name, null, null,
-//                                                         GSSContext.DEFAULT_LIFETIME);
-//              context.requestMutualAuth(true);
-//              context.requestReplayDet(true);
-//              context.requestSequenceDet(true);
-//              context.requestCredDeleg(true);
-//              byte []inToken = new byte[0];
-//              while (!context.isEstablished()) {
-//                  byte[] outToken
-//                      = context.initSecContext(inToken, 0, inToken.length);
-//                  // send the output token if generated
-//                  if (outToken != null) {
-//                      out.write(1);
-//                      out.write(1);
-//                      out.writeShort(outToken.length);
-//                      out.write(outToken);
-//                      out.flush();
-//                      data = new byte[2];
-//                      i = readSocksReply(in, data, deadlineMillis);
-//                      if (i != 2 || data[1] == 0xff) {
-//                          in.close();
-//                          out.close();
-//                          return false;
-//                      }
-//                      i = readSocksReply(in, data, deadlineMillis);
-//                      int len = 0;
-//                      len = ((int)data[0] & 0xff) << 8;
-//                      len += data[1];
-//                      data = new byte[len];
-//                      i = readSocksReply(in, data, deadlineMillis);
-//                      if (i == len)
-//                          return true;
-//                      in.close();
-//                      out.close();
-//                  }
-//              }
-//          } catch (GSSException e) {
-//              /* RFC 1961 states that if Context initialisation fails the connection
-//                 MUST be closed */
-//              e.printStackTrace();
-//              in.close();
-//              out.close();
-//          }
-//      }
         return false;
     }
 
@@ -592,450 +518,6 @@
         external_address = epoint;
     }
 
-    private void bindV4(InputStream in, OutputStream out,
-                        InetAddress baddr,
-                        int lport) throws IOException {
-        if (!(baddr instanceof Inet4Address)) {
-            throw new SocketException("SOCKS V4 requires IPv4 only addresses");
-        }
-        super.bind(baddr, lport);
-        byte[] addr1 = baddr.getAddress();
-        /* Test for AnyLocal */
-        InetAddress naddr = baddr;
-        if (naddr.isAnyLocalAddress()) {
-            naddr = AccessController.doPrivileged(
-                        new PrivilegedAction<>() {
-                            public InetAddress run() {
-                                return cmdsock.getLocalAddress();
-
-                            }
-                        });
-            addr1 = naddr.getAddress();
-        }
-        out.write(PROTO_VERS4);
-        out.write(BIND);
-        out.write((super.getLocalPort() >> 8) & 0xff);
-        out.write((super.getLocalPort() >> 0) & 0xff);
-        out.write(addr1);
-        String userName = getUserName();
-        try {
-            out.write(userName.getBytes("ISO-8859-1"));
-        } catch (java.io.UnsupportedEncodingException uee) {
-            assert false;
-        }
-        out.write(0);
-        out.flush();
-        byte[] data = new byte[8];
-        int n = readSocksReply(in, data);
-        if (n != 8)
-            throw new SocketException("Reply from SOCKS server has bad length: " + n);
-        if (data[0] != 0 && data[0] != 4)
-            throw new SocketException("Reply from SOCKS server has bad version");
-        SocketException ex = null;
-        switch (data[1]) {
-        case 90:
-            // Success!
-            external_address = new InetSocketAddress(baddr, lport);
-            break;
-        case 91:
-            ex = new SocketException("SOCKS request rejected");
-            break;
-        case 92:
-            ex = new SocketException("SOCKS server couldn't reach destination");
-            break;
-        case 93:
-            ex = new SocketException("SOCKS authentication failed");
-            break;
-        default:
-            ex = new SocketException("Reply from SOCKS server contains bad status");
-            break;
-        }
-        if (ex != null) {
-            in.close();
-            out.close();
-            throw ex;
-        }
-
-    }
-
-    /**
-     * Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind
-     * means "accept incoming connection from", so the SocketAddress is
-     * the one of the host we do accept connection from.
-     *
-     * @param      saddr   the Socket address of the remote host.
-     * @exception  IOException  if an I/O error occurs when binding this socket.
-     */
-    protected synchronized void socksBind(InetSocketAddress saddr) throws IOException {
-        if (((SocketImpl) this).socket != null) {
-            // this is a client socket, not a server socket, don't
-            // call the SOCKS proxy for a bind!
-            return;
-        }
-
-        // Connects to the SOCKS server
-
-        if (server == null) {
-            // This is the general case
-            // server is not null only when the socket was created with a
-            // specified proxy in which case it does bypass the ProxySelector
-            ProxySelector sel = java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction<>() {
-                    public ProxySelector run() {
-                            return ProxySelector.getDefault();
-                        }
-                    });
-            if (sel == null) {
-                /*
-                 * No default proxySelector --> direct connection
-                 */
-                return;
-            }
-            URI uri;
-            // Use getHostString() to avoid reverse lookups
-            String host = saddr.getHostString();
-            // IPv6 literal?
-            if (saddr.getAddress() instanceof Inet6Address &&
-                (!host.startsWith("[")) && (host.indexOf(':') >= 0)) {
-                host = "[" + host + "]";
-            }
-            try {
-                uri = new URI("serversocket://" + ParseUtil.encodePath(host) + ":"+ saddr.getPort());
-            } catch (URISyntaxException e) {
-                // This shouldn't happen
-                assert false : e;
-                uri = null;
-            }
-            Proxy p = null;
-            Exception savedExc = null;
-            java.util.Iterator<Proxy> iProxy = null;
-            iProxy = sel.select(uri).iterator();
-            if (iProxy == null || !(iProxy.hasNext())) {
-                return;
-            }
-            while (iProxy.hasNext()) {
-                p = iProxy.next();
-                if (p == null || p.type() != Proxy.Type.SOCKS) {
-                    return;
-                }
-
-                if (!(p.address() instanceof InetSocketAddress))
-                    throw new SocketException("Unknown address type for proxy: " + p);
-                // Use getHostString() to avoid reverse lookups
-                server = ((InetSocketAddress) p.address()).getHostString();
-                serverPort = ((InetSocketAddress) p.address()).getPort();
-                useV4 = useV4(p);
-
-                // Connects to the SOCKS server
-                try {
-                    AccessController.doPrivileged(
-                        new PrivilegedExceptionAction<>() {
-                            public Void run() throws Exception {
-                                cmdsock = new Socket(new NioSocketImpl(false));
-                                cmdsock.connect(new InetSocketAddress(server, serverPort));
-                                cmdIn = cmdsock.getInputStream();
-                                cmdOut = cmdsock.getOutputStream();
-                                return null;
-                            }
-                        });
-                } catch (Exception e) {
-                    // Ooops, let's notify the ProxySelector
-                    sel.connectFailed(uri,p.address(),new SocketException(e.getMessage()));
-                    server = null;
-                    serverPort = -1;
-                    cmdsock = null;
-                    savedExc = e;
-                    // Will continue the while loop and try the next proxy
-                }
-            }
-
-            /*
-             * If server is still null at this point, none of the proxy
-             * worked
-             */
-            if (server == null || cmdsock == null) {
-                throw new SocketException("Can't connect to SOCKS proxy:"
-                                          + savedExc.getMessage());
-            }
-        } else {
-            try {
-                AccessController.doPrivileged(
-                    new PrivilegedExceptionAction<>() {
-                        public Void run() throws Exception {
-                            cmdsock = new Socket(new NioSocketImpl(false));
-                            cmdsock.connect(new InetSocketAddress(server, serverPort));
-                            cmdIn = cmdsock.getInputStream();
-                            cmdOut = cmdsock.getOutputStream();
-                            return null;
-                        }
-                    });
-            } catch (Exception e) {
-                throw new SocketException(e.getMessage());
-            }
-        }
-        BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512);
-        InputStream in = cmdIn;
-        if (useV4) {
-            bindV4(in, out, saddr.getAddress(), saddr.getPort());
-            return;
-        }
-        out.write(PROTO_VERS);
-        out.write(2);
-        out.write(NO_AUTH);
-        out.write(USER_PASSW);
-        out.flush();
-        byte[] data = new byte[2];
-        int i = readSocksReply(in, data);
-        if (i != 2 || ((int)data[0]) != PROTO_VERS) {
-            // Maybe it's not a V5 sever after all
-            // Let's try V4 before we give up
-            bindV4(in, out, saddr.getAddress(), saddr.getPort());
-            return;
-        }
-        if (((int)data[1]) == NO_METHODS)
-            throw new SocketException("SOCKS : No acceptable methods");
-        if (!authenticate(data[1], in, out)) {
-            throw new SocketException("SOCKS : authentication failed");
-        }
-        // We're OK. Let's issue the BIND command.
-        out.write(PROTO_VERS);
-        out.write(BIND);
-        out.write(0);
-        int lport = saddr.getPort();
-        if (saddr.isUnresolved()) {
-            out.write(DOMAIN_NAME);
-            out.write(saddr.getHostName().length());
-            try {
-                out.write(saddr.getHostName().getBytes("ISO-8859-1"));
-            } catch (java.io.UnsupportedEncodingException uee) {
-                assert false;
-            }
-            out.write((lport >> 8) & 0xff);
-            out.write((lport >> 0) & 0xff);
-        } else if (saddr.getAddress() instanceof Inet4Address) {
-            byte[] addr1 = saddr.getAddress().getAddress();
-            out.write(IPV4);
-            out.write(addr1);
-            out.write((lport >> 8) & 0xff);
-            out.write((lport >> 0) & 0xff);
-            out.flush();
-        } else if (saddr.getAddress() instanceof Inet6Address) {
-            byte[] addr1 = saddr.getAddress().getAddress();
-            out.write(IPV6);
-            out.write(addr1);
-            out.write((lport >> 8) & 0xff);
-            out.write((lport >> 0) & 0xff);
-            out.flush();
-        } else {
-            cmdsock.close();
-            throw new SocketException("unsupported address type : " + saddr);
-        }
-        data = new byte[4];
-        i = readSocksReply(in, data);
-        SocketException ex = null;
-        int len, nport;
-        byte[] addr;
-        switch (data[1]) {
-        case REQUEST_OK:
-            // success!
-            switch(data[3]) {
-            case IPV4:
-                addr = new byte[4];
-                i = readSocksReply(in, addr);
-                if (i != 4)
-                    throw new SocketException("Reply from SOCKS server badly formatted");
-                data = new byte[2];
-                i = readSocksReply(in, data);
-                if (i != 2)
-                    throw new SocketException("Reply from SOCKS server badly formatted");
-                nport = ((int)data[0] & 0xff) << 8;
-                nport += ((int)data[1] & 0xff);
-                external_address =
-                    new InetSocketAddress(new Inet4Address("", addr) , nport);
-                break;
-            case DOMAIN_NAME:
-                len = data[1];
-                byte[] host = new byte[len];
-                i = readSocksReply(in, host);
-                if (i != len)
-                    throw new SocketException("Reply from SOCKS server badly formatted");
-                data = new byte[2];
-                i = readSocksReply(in, data);
-                if (i != 2)
-                    throw new SocketException("Reply from SOCKS server badly formatted");
-                nport = ((int)data[0] & 0xff) << 8;
-                nport += ((int)data[1] & 0xff);
-                external_address = new InetSocketAddress(new String(host), nport);
-                break;
-            case IPV6:
-                len = data[1];
-                addr = new byte[len];
-                i = readSocksReply(in, addr);
-                if (i != len)
-                    throw new SocketException("Reply from SOCKS server badly formatted");
-                data = new byte[2];
-                i = readSocksReply(in, data);
-                if (i != 2)
-                    throw new SocketException("Reply from SOCKS server badly formatted");
-                nport = ((int)data[0] & 0xff) << 8;
-                nport += ((int)data[1] & 0xff);
-                external_address =
-                    new InetSocketAddress(new Inet6Address("", addr), nport);
-                break;
-            }
-            break;
-        case GENERAL_FAILURE:
-            ex = new SocketException("SOCKS server general failure");
-            break;
-        case NOT_ALLOWED:
-            ex = new SocketException("SOCKS: Bind not allowed by ruleset");
-            break;
-        case NET_UNREACHABLE:
-            ex = new SocketException("SOCKS: Network unreachable");
-            break;
-        case HOST_UNREACHABLE:
-            ex = new SocketException("SOCKS: Host unreachable");
-            break;
-        case CONN_REFUSED:
-            ex = new SocketException("SOCKS: Connection refused");
-            break;
-        case TTL_EXPIRED:
-            ex =  new SocketException("SOCKS: TTL expired");
-            break;
-        case CMD_NOT_SUPPORTED:
-            ex = new SocketException("SOCKS: Command not supported");
-            break;
-        case ADDR_TYPE_NOT_SUP:
-            ex = new SocketException("SOCKS: address type not supported");
-            break;
-        }
-        if (ex != null) {
-            in.close();
-            out.close();
-            cmdsock.close();
-            cmdsock = null;
-            throw ex;
-        }
-        cmdIn = in;
-        cmdOut = out;
-    }
-
-    /**
-     * Accepts a connection from a specific host.
-     *
-     * @param      s   the accepted connection.
-     * @param      saddr the socket address of the host we do accept
-     *               connection from
-     * @exception  IOException  if an I/O error occurs when accepting the
-     *               connection.
-     */
-    protected void acceptFrom(SocketImpl s, InetSocketAddress saddr) throws IOException {
-        if (cmdsock == null) {
-            // Not a Socks ServerSocket.
-            return;
-        }
-        InputStream in = cmdIn;
-        // Sends the "SOCKS BIND" request.
-        socksBind(saddr);
-        in.read();
-        int i = in.read();
-        in.read();
-        SocketException ex = null;
-        int nport;
-        byte[] addr;
-        InetSocketAddress real_end = null;
-        switch (i) {
-        case REQUEST_OK:
-            // success!
-            i = in.read();
-            switch(i) {
-            case IPV4:
-                addr = new byte[4];
-                readSocksReply(in, addr);
-                nport = in.read() << 8;
-                nport += in.read();
-                real_end =
-                    new InetSocketAddress(new Inet4Address("", addr) , nport);
-                break;
-            case DOMAIN_NAME:
-                int len = in.read();
-                addr = new byte[len];
-                readSocksReply(in, addr);
-                nport = in.read() << 8;
-                nport += in.read();
-                real_end = new InetSocketAddress(new String(addr), nport);
-                break;
-            case IPV6:
-                addr = new byte[16];
-                readSocksReply(in, addr);
-                nport = in.read() << 8;
-                nport += in.read();
-                real_end =
-                    new InetSocketAddress(new Inet6Address("", addr), nport);
-                break;
-            }
-            break;
-        case GENERAL_FAILURE:
-            ex = new SocketException("SOCKS server general failure");
-            break;
-        case NOT_ALLOWED:
-            ex = new SocketException("SOCKS: Accept not allowed by ruleset");
-            break;
-        case NET_UNREACHABLE:
-            ex = new SocketException("SOCKS: Network unreachable");
-            break;
-        case HOST_UNREACHABLE:
-            ex = new SocketException("SOCKS: Host unreachable");
-            break;
-        case CONN_REFUSED:
-            ex = new SocketException("SOCKS: Connection refused");
-            break;
-        case TTL_EXPIRED:
-            ex =  new SocketException("SOCKS: TTL expired");
-            break;
-        case CMD_NOT_SUPPORTED:
-            ex = new SocketException("SOCKS: Command not supported");
-            break;
-        case ADDR_TYPE_NOT_SUP:
-            ex = new SocketException("SOCKS: address type not supported");
-            break;
-        }
-        if (ex != null) {
-            cmdIn.close();
-            cmdOut.close();
-            cmdsock.close();
-            cmdsock = null;
-            throw ex;
-        }
-
-        /**
-         * This is where we have to do some fancy stuff.
-         * The datastream from the socket "accepted" by the proxy will
-         * come through the cmdSocket. So we have to swap the socketImpls
-         */
-        if (s instanceof SocksSocketImpl) {
-            ((SocksSocketImpl)s).external_address = real_end;
-        }
-        if (s instanceof PlainSocketImpl) {
-            PlainSocketImpl psi = (PlainSocketImpl) s;
-            psi.setInputStream((SocketInputStream) in);
-            psi.setFileDescriptor(cmdsock.getImpl().getFileDescriptor());
-            psi.setAddress(cmdsock.getImpl().getInetAddress());
-            psi.setPort(cmdsock.getImpl().getPort());
-            psi.setLocalPort(cmdsock.getImpl().getLocalPort());
-        } else {
-            s.fd = cmdsock.getImpl().fd;
-            s.address = cmdsock.getImpl().address;
-            s.port = cmdsock.getImpl().port;
-            s.localport = cmdsock.getImpl().localport;
-        }
-
-        // Need to do that so that the socket won't be closed
-        // when the ServerSocket is closed by the user.
-        // It kinds of detaches the Socket because it is now
-        // used elsewhere.
-        cmdsock = null;
-    }
 
 
     /**
@@ -1075,14 +557,6 @@
     }
 
     private String getUserName() {
-        String userName = "";
-        if (applicationSetProxy) {
-            try {
-                userName = System.getProperty("user.name");
-            } catch (SecurityException se) { /* swallow Exception */ }
-        } else {
-            userName = StaticProperty.userName();
-        }
-        return userName;
+        return StaticProperty.userName();
     }
 }
--- a/src/java.base/share/classes/java/util/Base64.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.base/share/classes/java/util/Base64.java	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -186,6 +186,10 @@
      * a method of this class will cause a
      * {@link java.lang.NullPointerException NullPointerException} to
      * be thrown.
+     * <p> If the encoded byte output of the needed size can not
+     *     be allocated, the encode methods of this class will
+     *     cause an {@link java.lang.OutOfMemoryError OutOfMemoryError}
+     *     to be thrown.
      *
      * @see     Decoder
      * @since   1.8
@@ -237,16 +241,37 @@
         static final Encoder RFC4648_URLSAFE = new Encoder(true, null, -1, true);
         static final Encoder RFC2045 = new Encoder(false, CRLF, MIMELINEMAX, true);
 
-        private final int outLength(int srclen) {
+        /**
+         * Calculates the length of the encoded output bytes.
+         *
+         * @param srclen length of the bytes to encode
+         * @param throwOOME if true, throws OutOfMemoryError if the length of
+         *                  the encoded bytes overflows; else returns the
+         *                  length
+         * @return length of the encoded bytes, or -1 if the length overflows
+         *
+         */
+        private final int outLength(int srclen, boolean throwOOME) {
             int len = 0;
-            if (doPadding) {
-                len = 4 * ((srclen + 2) / 3);
-            } else {
-                int n = srclen % 3;
-                len = 4 * (srclen / 3) + (n == 0 ? 0 : n + 1);
+            try {
+                if (doPadding) {
+                    len = Math.multiplyExact(4, (Math.addExact(srclen, 2) / 3));
+                } else {
+                    int n = srclen % 3;
+                    len = Math.addExact(Math.multiplyExact(4, (srclen / 3)), (n == 0 ? 0 : n + 1));
+                }
+                if (linemax > 0) {                             // line separators
+                    len = Math.addExact(len, (len - 1) / linemax * newline.length);
+                }
+            } catch (ArithmeticException ex) {
+                if (throwOOME) {
+                    throw new OutOfMemoryError("Encoded size is too large");
+                } else {
+                    // let the caller know that encoded bytes length
+                    // is too large
+                    len = -1;
+                }
             }
-            if (linemax > 0)                                  // line separators
-                len += (len - 1) / linemax * newline.length;
             return len;
         }
 
@@ -261,7 +286,7 @@
          *          encoded bytes.
          */
         public byte[] encode(byte[] src) {
-            int len = outLength(src.length);          // dst array size
+            int len = outLength(src.length, true);          // dst array size
             byte[] dst = new byte[len];
             int ret = encode0(src, 0, src.length, dst);
             if (ret != dst.length)
@@ -289,8 +314,8 @@
          *          space for encoding all input bytes.
          */
         public int encode(byte[] src, byte[] dst) {
-            int len = outLength(src.length);         // dst array size
-            if (dst.length < len)
+            int len = outLength(src.length, false);         // dst array size
+            if (dst.length < len || len == -1)
                 throw new IllegalArgumentException(
                     "Output byte array is too small for encoding all input bytes");
             return encode0(src, 0, src.length, dst);
@@ -334,7 +359,7 @@
          * @return  A newly-allocated byte buffer containing the encoded bytes.
          */
         public ByteBuffer encode(ByteBuffer buffer) {
-            int len = outLength(buffer.remaining());
+            int len = outLength(buffer.remaining(), true);
             byte[] dst = new byte[len];
             int ret = 0;
             if (buffer.hasArray()) {
@@ -469,6 +494,10 @@
      * a method of this class will cause a
      * {@link java.lang.NullPointerException NullPointerException} to
      * be thrown.
+     * <p> If the decoded byte output of the needed size can not
+     *     be allocated, the decode methods of this class will
+     *     cause an {@link java.lang.OutOfMemoryError OutOfMemoryError}
+     *     to be thrown.
      *
      * @see     Encoder
      * @since   1.8
@@ -531,7 +560,7 @@
          *          if {@code src} is not in valid Base64 scheme
          */
         public byte[] decode(byte[] src) {
-            byte[] dst = new byte[outLength(src, 0, src.length)];
+            byte[] dst = new byte[outLength(src, 0, src.length, true)];
             int ret = decode0(src, 0, src.length, dst);
             if (ret != dst.length) {
                 dst = Arrays.copyOf(dst, ret);
@@ -584,8 +613,8 @@
          *          does not have enough space for decoding all input bytes.
          */
         public int decode(byte[] src, byte[] dst) {
-            int len = outLength(src, 0, src.length);
-            if (dst.length < len)
+            int len = outLength(src, 0, src.length, false);
+            if (dst.length < len || len == -1)
                 throw new IllegalArgumentException(
                     "Output byte array is too small for decoding all input bytes");
             return decode0(src, 0, src.length, dst);
@@ -610,7 +639,7 @@
          * @return  A newly-allocated byte buffer containing the decoded bytes
          *
          * @throws  IllegalArgumentException
-         *          if {@code src} is not in valid Base64 scheme.
+         *          if {@code buffer} is not in valid Base64 scheme
          */
         public ByteBuffer decode(ByteBuffer buffer) {
             int pos0 = buffer.position();
@@ -628,7 +657,7 @@
                     sp = 0;
                     sl = src.length;
                 }
-                byte[] dst = new byte[outLength(src, sp, sl)];
+                byte[] dst = new byte[outLength(src, sp, sl, true)];
                 return ByteBuffer.wrap(dst, 0, decode0(src, sp, sl, dst));
             } catch (IllegalArgumentException iae) {
                 buffer.position(pos0);
@@ -656,7 +685,19 @@
             return new DecInputStream(is, isURL ? fromBase64URL : fromBase64, isMIME);
         }
 
-        private int outLength(byte[] src, int sp, int sl) {
+        /**
+         * Calculates the length of the decoded output bytes.
+         *
+         * @param src the byte array to decode
+         * @param sp the source  position
+         * @param sl the source limit
+         * @param throwOOME if true, throws OutOfMemoryError if the length of
+         *                  the decoded bytes overflows; else returns the
+         *                  length
+         * @return length of the decoded bytes, or -1 if the length overflows
+         *
+         */
+        private int outLength(byte[] src, int sp, int sl, boolean throwOOME) {
             int[] base64 = isURL ? fromBase64URL : fromBase64;
             int paddings = 0;
             int len = sl - sp;
@@ -691,7 +732,19 @@
             }
             if (paddings == 0 && (len & 0x3) !=  0)
                 paddings = 4 - (len & 0x3);
-            return 3 * ((len + 3) / 4) - paddings;
+
+            try {
+                len = Math.multiplyExact(3, (Math.addExact(len, 3) / 4)) - paddings;
+            } catch (ArithmeticException ex) {
+                if (throwOOME) {
+                    throw new OutOfMemoryError("Decoded size is too large");
+                } else {
+                    // let the caller know that the decoded bytes length
+                    // is too large
+                    len = -1;
+                }
+            }
+            return len;
         }
 
         private int decode0(byte[] src, int sp, int sl, byte[] dst) {
--- a/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java	Thu Jan 24 17:29:21 2019 +0000
@@ -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
@@ -148,6 +148,12 @@
 
     private void deriveFallbackName(String[] names, int index, Locale locale, boolean noDST) {
         if (exists(names, index)) {
+            if (names[index].equals(NO_INHERITANCE_MARKER)) {
+                // CLDR's "no inheritance marker"
+                names[index] = toGMTFormat(names[INDEX_TZID],
+                                    index == INDEX_DST_LONG || index == INDEX_DST_SHORT,
+                                    index % 2 != 0, locale);
+            }
             return;
         }
 
--- a/src/java.net.http/share/classes/jdk/internal/net/http/BufferingSubscriber.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/BufferingSubscriber.java	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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,14 +37,14 @@
 import java.net.http.HttpResponse.BodySubscriber;
 import jdk.internal.net.http.common.Demand;
 import jdk.internal.net.http.common.SequentialScheduler;
-import jdk.internal.net.http.common.Utils;
+import jdk.internal.net.http.ResponseSubscribers.TrustedSubscriber;
 
 /**
  * A buffering BodySubscriber. When subscribed, accumulates ( buffers ) a given
  * amount ( in bytes ) of a publisher's data before pushing it to a downstream
  * subscriber.
  */
-public class BufferingSubscriber<T> implements BodySubscriber<T>
+public class BufferingSubscriber<T> implements TrustedSubscriber<T>
 {
     /** The downstream consumer of the data. */
     private final BodySubscriber<T> downstreamSubscriber;
@@ -94,6 +94,11 @@
         return buffers.stream().mapToLong(ByteBuffer::remaining).sum();
     }
 
+    @Override
+    public boolean needsExecutor() {
+        return TrustedSubscriber.needsExecutor(downstreamSubscriber);
+    }
+
     /**
      * Tells whether, or not, there is at least a sufficient number of bytes
      * accumulated in the internal buffers. If the subscriber is COMPLETE, and
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -34,6 +34,7 @@
 import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Flow;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
@@ -199,7 +200,11 @@
     private void flush() {
         ByteBuffer buf;
         try {
-            assert !client.isSelectorThread() :
+            // we should not be running in the selector here,
+            // except if the custom Executor supplied to the client is
+            // something like (r) -> r.run();
+           assert !client.isSelectorThread()
+                   || !(client.theExecutor().delegate() instanceof ExecutorService) :
                     "Http1AsyncReceiver::flush should not run in the selector: "
                     + Thread.currentThread().getName();
 
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java	Thu Jan 24 17:29:21 2019 +0000
@@ -41,6 +41,7 @@
 import java.net.http.HttpResponse;
 import jdk.internal.net.http.ResponseContent.BodyParser;
 import jdk.internal.net.http.ResponseContent.UnknownLengthBodyParser;
+import jdk.internal.net.http.ResponseSubscribers.TrustedSubscriber;
 import jdk.internal.net.http.common.Log;
 import jdk.internal.net.http.common.Logger;
 import jdk.internal.net.http.common.MinimalFuture;
@@ -293,7 +294,7 @@
      * subscribed.
      * @param <U> The type of response.
      */
-    final static class Http1BodySubscriber<U> implements HttpResponse.BodySubscriber<U> {
+    final static class Http1BodySubscriber<U> implements TrustedSubscriber<U> {
         final HttpResponse.BodySubscriber<U> userSubscriber;
         final AtomicBoolean completed = new AtomicBoolean();
         volatile Throwable withError;
@@ -302,6 +303,11 @@
             this.userSubscriber = userSubscriber;
         }
 
+        @Override
+        public boolean needsExecutor() {
+            return TrustedSubscriber.needsExecutor(userSubscriber);
+        }
+
         // propagate the error to the user subscriber, even if not
         // subscribed yet.
         private void propagateError(Throwable t) {
@@ -356,6 +362,7 @@
         public CompletionStage<U> getBody() {
             return userSubscriber.getBody();
         }
+
         @Override
         public void onSubscribe(Flow.Subscription subscription) {
             if (!subscribed) {
@@ -475,18 +482,12 @@
                 connection.client().unreference();
             }
         });
-        try {
-            p.getBody().whenComplete((U u, Throwable t) -> {
-                if (t == null)
-                    cf.complete(u);
-                else
-                    cf.completeExceptionally(t);
-            });
-        } catch (Throwable t) {
+
+        ResponseSubscribers.getBodyAsync(executor, p, cf, (t) -> {
             cf.completeExceptionally(t);
             asyncReceiver.setRetryOnError(false);
             asyncReceiver.onReadError(t);
-        }
+        });
 
         return cf.whenComplete((s,t) -> {
             if (t != null) {
--- a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java	Thu Jan 24 17:29:21 2019 +0000
@@ -271,9 +271,9 @@
     private CompletableFuture<HttpResponse<T>> handleNoBody(Response r, Exchange<T> exch) {
         BodySubscriber<T> bs = responseHandler.apply(new ResponseInfoImpl(r.statusCode(),
                 r.headers(), r.version()));
-        CompletionStage<T> cs = bs.getBody();
         bs.onSubscribe(new NullSubscription());
         bs.onComplete();
+        CompletionStage<T> cs = ResponseSubscribers.getBodyAsync(executor, bs);
         MinimalFuture<HttpResponse<T>> result = new MinimalFuture<>();
         cs.whenComplete((nullBody, exception) -> {
             if (exception != null)
--- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java	Thu Jan 24 17:29:21 2019 +0000
@@ -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
@@ -30,9 +30,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.lang.System.Logger.Level;
-import java.net.http.HttpHeaders;
-import java.net.http.HttpResponse;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.charset.Charset;
@@ -50,6 +47,7 @@
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
 import java.util.concurrent.Flow;
 import java.util.concurrent.Flow.Subscriber;
 import java.util.concurrent.Flow.Subscription;
@@ -67,7 +65,50 @@
 
 public class ResponseSubscribers {
 
-    public static class ConsumerSubscriber implements BodySubscriber<Void> {
+    /**
+     * This interface is used by our BodySubscriber implementations to
+     * declare whether calling getBody() inline is safe, or whether
+     * it needs to be called asynchronously in an executor thread.
+     * Calling getBody() inline is usually safe except when it
+     * might block - which can be the case if the BodySubscriber
+     * is provided by custom code, or if it uses a finisher that
+     * might be called and might block before the last bit is
+     * received (for instance, if a mapping subscriber is used with
+     * a mapper function that maps an InputStream to a GZIPInputStream,
+     * as the the constructor of GZIPInputStream calls read()).
+     * @param <T> The response type.
+     */
+    public interface TrustedSubscriber<T> extends BodySubscriber<T> {
+        /**
+         * Returns true if getBody() should be called asynchronously.
+         * @implSpec The default implementation of this method returns
+         *           false.
+         * @return true if getBody() should be called asynchronously.
+         */
+        default boolean needsExecutor() { return false;}
+
+        /**
+         * Returns true if calling {@code bs::getBody} might block
+         * and requires an executor.
+         *
+         * @implNote
+         * In particular this method returns
+         * true if {@code bs} is not a {@code TrustedSubscriber}.
+         * If it is a {@code TrustedSubscriber}, it returns
+         * {@code ((TrustedSubscriber) bs).needsExecutor()}.
+         *
+         * @param bs A BodySubscriber.
+         * @return true if calling {@code bs::getBody} requires using
+         *         an executor.
+         */
+        static boolean needsExecutor(BodySubscriber<?> bs) {
+            if (bs instanceof TrustedSubscriber) {
+                return ((TrustedSubscriber) bs).needsExecutor();
+            } else return true;
+        }
+    }
+
+    public static class ConsumerSubscriber implements TrustedSubscriber<Void> {
         private final Consumer<Optional<byte[]>> consumer;
         private Flow.Subscription subscription;
         private final CompletableFuture<Void> result = new MinimalFuture<>();
@@ -122,7 +163,7 @@
      * asserts the specific, write, file permissions that were checked during
      * the construction of this PathSubscriber.
      */
-    public static class PathSubscriber implements BodySubscriber<Path> {
+    public static class PathSubscriber implements TrustedSubscriber<Path> {
 
         private static final FilePermission[] EMPTY_FILE_PERMISSIONS = new FilePermission[0];
 
@@ -223,7 +264,7 @@
         }
     }
 
-    public static class ByteArraySubscriber<T> implements BodySubscriber<T> {
+    public static class ByteArraySubscriber<T> implements TrustedSubscriber<T> {
         private final Function<byte[], T> finisher;
         private final CompletableFuture<T> result = new MinimalFuture<>();
         private final List<ByteBuffer> received = new ArrayList<>();
@@ -292,7 +333,7 @@
      * An InputStream built on top of the Flow API.
      */
     public static class HttpResponseInputStream extends InputStream
-        implements BodySubscriber<InputStream>
+        implements TrustedSubscriber<InputStream>
     {
         final static int MAX_BUFFERS_IN_QUEUE = 1;  // lock-step with the producer
 
@@ -410,6 +451,24 @@
         }
 
         @Override
+        public int available() throws IOException {
+            // best effort: returns the number of remaining bytes in
+            // the current buffer if any, or 1 if the current buffer
+            // is null or empty but the queue or current buffer list
+            // are not empty. Returns 0 otherwise.
+            if (closed) return 0;
+            int available = 0;
+            ByteBuffer current = currentBuffer;
+            if (current == LAST_BUFFER) return 0;
+            if (current != null) available = current.remaining();
+            if (available != 0) return available;
+            Iterator<?> iterator = currentListItr;
+            if (iterator != null && iterator.hasNext()) return 1;
+            if (buffers.isEmpty()) return 0;
+            return 1;
+        }
+
+        @Override
         public void onSubscribe(Flow.Subscription s) {
             try {
                 if (!subscribed.compareAndSet(false, true)) {
@@ -517,17 +576,19 @@
     public static BodySubscriber<Stream<String>> createLineStream(Charset charset) {
         Objects.requireNonNull(charset);
         BodySubscriber<InputStream> s = new HttpResponseInputStream();
+        // Creates a MappingSubscriber with a trusted finisher that is
+        // trusted not to block.
         return new MappingSubscriber<InputStream,Stream<String>>(s,
             (InputStream stream) -> {
                 return new BufferedReader(new InputStreamReader(stream, charset))
                             .lines().onClose(() -> Utils.close(stream));
-            });
+            }, true);
     }
 
     /**
      * Currently this consumes all of the data and ignores it
      */
-    public static class NullSubscriber<T> implements BodySubscriber<T> {
+    public static class NullSubscriber<T> implements TrustedSubscriber<T> {
 
         private final CompletableFuture<T> cf = new MinimalFuture<>();
         private final Optional<T> result;
@@ -573,13 +634,16 @@
 
     /** An adapter between {@code BodySubscriber} and {@code Flow.Subscriber}. */
     public static final class SubscriberAdapter<S extends Subscriber<? super List<ByteBuffer>>,R>
-        implements BodySubscriber<R>
+        implements TrustedSubscriber<R>
     {
         private final CompletableFuture<R> cf = new MinimalFuture<>();
         private final S subscriber;
         private final Function<? super S,? extends R> finisher;
         private volatile Subscription subscription;
 
+        // The finisher isn't called until all bytes have been received,
+        // and so shouldn't need an executor. No need to override
+        // TrustedSubscriber::needsExecutor
         public SubscriberAdapter(S subscriber, Function<? super S,? extends R> finisher) {
             this.subscriber = Objects.requireNonNull(subscriber);
             this.finisher = Objects.requireNonNull(finisher);
@@ -647,16 +711,40 @@
      * @param <T> the upstream body type
      * @param <U> this subscriber's body type
      */
-    public static class MappingSubscriber<T,U> implements BodySubscriber<U> {
+    public static class MappingSubscriber<T,U> implements TrustedSubscriber<U> {
         private final BodySubscriber<T> upstream;
         private final Function<? super T,? extends U> mapper;
+        private final boolean trusted;
 
         public MappingSubscriber(BodySubscriber<T> upstream,
                                  Function<? super T,? extends U> mapper) {
+            this(upstream, mapper, false);
+        }
+
+        // creates a MappingSubscriber with a mapper that is trusted
+        // to not block when called.
+        MappingSubscriber(BodySubscriber<T> upstream,
+                          Function<? super T,? extends U> mapper,
+                          boolean trusted) {
             this.upstream = Objects.requireNonNull(upstream);
             this.mapper = Objects.requireNonNull(mapper);
+            this.trusted = trusted;
         }
 
+        // There is no way to know whether a custom mapper function
+        // might block or not - so we should return true unless the
+        // mapper is implemented and trusted by our own code not to
+        // block.
+        @Override
+        public boolean needsExecutor() {
+            return !trusted || TrustedSubscriber.needsExecutor(upstream);
+        }
+
+        // If upstream.getBody() is already completed (case of InputStream),
+        // then calling upstream.getBody().thenApply(mapper) might block
+        // if the mapper blocks. We should probably add a variant of
+        // MappingSubscriber that calls thenApplyAsync instead, but this
+        // needs a new public API point. See needsExecutor() above.
         @Override
         public CompletionStage<U> getBody() {
             return upstream.getBody().thenApply(mapper);
@@ -685,7 +773,7 @@
 
     // A BodySubscriber that returns a Publisher<List<ByteBuffer>>
     static class PublishingBodySubscriber
-            implements BodySubscriber<Flow.Publisher<List<ByteBuffer>>> {
+            implements TrustedSubscriber<Flow.Publisher<List<ByteBuffer>>> {
         private final MinimalFuture<Flow.Subscription>
                 subscriptionCF = new MinimalFuture<>();
         private final MinimalFuture<SubscriberRef>
@@ -894,4 +982,110 @@
         return new PublishingBodySubscriber();
     }
 
+
+    /**
+     * Tries to determine whether bs::getBody must be invoked asynchronously,
+     * and if so, uses the provided executor to do it.
+     * If the executor is a {@link HttpClientImpl.DelegatingExecutor},
+     * uses the executor's delegate.
+     * @param e    The executor to use if an executor is required.
+     * @param bs   The BodySubscriber (trusted or not)
+     * @param <T>  The type of the response.
+     * @return A completion stage that completes when the completion
+     *         stage returned by bs::getBody completes. This may, or
+     *         may not, be the same completion stage.
+     */
+    public static <T> CompletionStage<T> getBodyAsync(Executor e, BodySubscriber<T> bs) {
+        if (TrustedSubscriber.needsExecutor(bs)) {
+            // getBody must be called in the executor
+            return getBodyAsync(e, bs, new MinimalFuture<>());
+        } else {
+            // No executor needed
+            return bs.getBody();
+        }
+    }
+
+    /**
+     * Invokes bs::getBody using the provided executor.
+     * If invoking bs::getBody requires an executor, and the given executor
+     * is a {@link HttpClientImpl.DelegatingExecutor}, then the executor's
+     * delegate is used. If an error occurs anywhere then the given {code cf}
+     * is completed exceptionally (this method does not throw).
+     * @param e   The executor that should be used to call bs::getBody
+     * @param bs  The BodySubscriber
+     * @param cf  A completable future that this function will set up
+     *            to complete when the completion stage returned by
+     *            bs::getBody completes.
+     *            In case of any error while trying to set up the
+     *            completion chain, {@code cf} will be completed
+     *            exceptionally with that error.
+     * @param <T> The response type.
+     * @return The provided {@code cf}.
+     */
+    public static <T> CompletableFuture<T> getBodyAsync(Executor e,
+                                                      BodySubscriber<T> bs,
+                                                      CompletableFuture<T> cf) {
+        return getBodyAsync(e, bs, cf, cf::completeExceptionally);
+    }
+
+    /**
+     * Invokes bs::getBody using the provided executor.
+     * If invoking bs::getBody requires an executor, and the given executor
+     * is a {@link HttpClientImpl.DelegatingExecutor}, then the executor's
+     * delegate is used.
+     * The provided {@code cf} is completed with the result (exceptional
+     * or not) of the completion stage returned by bs::getBody.
+     * If an error occurs when trying to set up the
+     * completion chain, the provided {@code errorHandler} is invoked,
+     * but {@code cf} is not necessarily affected.
+     * This method does not throw.
+     * @param e   The executor that should be used to call bs::getBody
+     * @param bs  The BodySubscriber
+     * @param cf  A completable future that this function will set up
+     *            to complete when the completion stage returned by
+     *            bs::getBody completes.
+     *            In case of any error while trying to set up the
+     *            completion chain, {@code cf} will be completed
+     *            exceptionally with that error.
+     * @param errorHandler The handler to invoke if an error is raised
+     *                     while trying to set up the completion chain.
+     * @param <T> The response type.
+     * @return The provide {@code cf}. If the {@code errorHandler} is
+     * invoked, it is the responsibility of the {@code errorHandler} to
+     * complete the {@code cf}, if needed.
+     */
+    public static <T> CompletableFuture<T> getBodyAsync(Executor e,
+                                                      BodySubscriber<T> bs,
+                                                      CompletableFuture<T> cf,
+                                                      Consumer<Throwable> errorHandler) {
+        assert errorHandler != null;
+        try {
+            assert e != null;
+            assert cf != null;
+
+            if (TrustedSubscriber.needsExecutor(bs)) {
+                e = (e instanceof HttpClientImpl.DelegatingExecutor)
+                        ? ((HttpClientImpl.DelegatingExecutor) e).delegate() : e;
+            }
+
+            e.execute(() -> {
+                try {
+                    bs.getBody().whenComplete((r, t) -> {
+                        if (t != null) {
+                            cf.completeExceptionally(t);
+                        } else {
+                            cf.complete(r);
+                        }
+                    });
+                } catch (Throwable t) {
+                    errorHandler.accept(t);
+                }
+            });
+            return cf;
+
+        } catch (Throwable t) {
+            errorHandler.accept(t);
+        }
+        return cf;
+    }
 }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, 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
@@ -333,21 +333,10 @@
     // pushes entire response body into response subscriber
     // blocking when required by local or remote flow control
     CompletableFuture<T> receiveData(BodySubscriber<T> bodySubscriber, Executor executor) {
-        responseBodyCF = new MinimalFuture<>();
         // We want to allow the subscriber's getBody() method to block so it
         // can work with InputStreams. So, we offload execution.
-        executor.execute(() -> {
-            try {
-                bodySubscriber.getBody().whenComplete((T body, Throwable t) -> {
-                    if (t == null)
-                        responseBodyCF.complete(body);
-                    else
-                        responseBodyCF.completeExceptionally(t);
-                });
-            } catch(Throwable t) {
-                cancelImpl(t);
-            }
-        });
+        responseBodyCF = ResponseSubscribers.getBodyAsync(executor, bodySubscriber,
+                new MinimalFuture<>(), this::cancelImpl);
 
         if (isCanceled()) {
             Throwable t = getCancelCause();
--- a/test/Makefile	Thu Jan 24 17:11:10 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-#
-# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# 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.
-#
-
-#
-# Makefile to run tests from multiple sibling directories
-#
-
-$(info WARNING: This way of running tests ("cd test && make") is deprecated)
-$(info Please use "make test TEST=..." instead. See doc/testing.md for details)
-
-# Macro to run a test target in a subdir
-define SUBDIR_TEST # subdirectory target
-if [ -d $1 ] ; then \
-  if [ -r $1/Makefile ] ; then \
-    $(MAKE) --no-print-directory -k -C $1 $2 ; \
-    echo 'WARNING: This way of running tests ("cd test && make") is deprecated' ; \
-    echo 'Please use "make test TEST=..." instead. See doc/testing.md for details' ; \
-  else \
-    echo "ERROR: File does not exist: $1/Makefile"; \
-    exit 1; \
-  fi; \
-else \
-  echo "WARNING: No testing done, directory does not exist: $1"; \
-fi
-endef
-
-# Default test target (core)
-default: jdk_core langtools_jtreg jaxp_all
-
-# All testing
-all: jdk_all langtools_all jaxp_all
-
-ifeq ($(TEST_JOBS), 0)
-  JDK_TEST_JOBS=$(JOBS)
-else
-  JDK_TEST_JOBS=$(TEST_JOBS)
-endif
-# Test targets
-langtools_% :
-	@$(NO_STOPPING)$(call SUBDIR_TEST, langtools, \
-	    $(if $(JDK_TEST_JOBS), CONCURRENCY=$(JDK_TEST_JOBS)) \
-	    JT_JAVA=$(PRODUCT_HOME) JTREG_HOME=$(JT_HOME) \
-	    TEST="$(subst langtools_,,$@)" $(subst langtools_,,$@))
-
-jdk_% core_%s svc_%:
-	@$(NO_STOPPING)$(call SUBDIR_TEST, jdk, \
-	    $(if $(JDK_TEST_JOBS), CONCURRENCY=$(JDK_TEST_JOBS)) TEST="$@" $@)
-
-jaxp_%:
-	@$(NO_STOPPING)$(call SUBDIR_TEST, jaxp, \
-	    $(if $(JDK_TEST_JOBS), CONCURRENCY=$(JDK_TEST_JOBS)) TEST="$@" $@)
-
-nashorn_%:
-	@$(NO_STOPPING)$(call SUBDIR_TEST, nashorn, \
-	    $(if $(JDK_TEST_JOBS), CONCURRENCY=$(JDK_TEST_JOBS)) TEST="$@" $@)
-
-SUB_MAKE_ARGS :=
-ifneq ($(TEST_JOBS), 0)
-  ifneq ($(TEST_JOBS), )
-    SUB_MAKE_ARGS += CONCURRENCY=$(TEST_JOBS)
-  endif
-endif
-hotspot_%:
-	@$(NO_STOPPING)$(call SUBDIR_TEST, hotspot/jtreg, $(SUB_MAKE_ARGS) TEST="$@" $@)
-
-#
-# jtreg_tests
-#
-# Invocation:
-#
-# make jtreg_tests TESTDIRS=<test-dirs> TEST_SELECTION=<path to test or jtreg group> TEST_OUTPUT_DIR=<path>
-#
-# where <test-dirs> is something like '../<component>/test/runtime',
-# <component> in turn being one of the top level directories (for
-# example 'hotspot').
-#
-# The below will strip the path prefix and delegate to the
-# corresponding ../<component>/test/Makefile.
-
-ifneq ($(TESTDIRS),)
-  # Extract the component from ../test/<component>/...
-  TESTDIRS_NORM := $(patsubst test/%, %, $(patsubst ../%, %, $(TESTDIRS)))
-  COMPONENT := $(word 1,$(subst /, ,$(TESTDIRS_NORM)))
-
-  # Strip off the ../<component>/test prefix and pass the rest as TESTDIRS
-  # to the delegate Makefile
-  # The hotspot tests are in a subdir "java". Accept paths both including
-  # and excluding this extra subdir
-  TESTDIRS_TESTS := $(patsubst $(COMPONENT)/%,%,$(patsubst hotspot/jtreg/%,%, \
-      $(patsubst ../%, %, $(TESTDIRS_NORM))))
-endif
-
-jtreg_tests:
-	$(MAKE) --no-print-directory TESTDIRS=$(TESTDIRS_TESTS) \
-	    $(COMPONENT)_jtreg_tests
-
-################################################################
-
-# Phony targets (e.g. these are not filenames)
-.PHONY: all clean
-
-################################################################
--- a/test/TestCommon.gmk	Thu Jan 24 17:11:10 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,472 +0,0 @@
-#
-# Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-#
-# Common logic to run various tests for a component, to be included by the
-# component specific test makefiles.
-#
-
-# Default values for some properties that can be overridden by components.
-USE_JTREG_VERSION ?= 4.2
-JTREG_VM_TYPE ?= -agentvm
-USE_JTREG_ASSERT ?= true
-LIMIT_JTREG_VM_MEMORY ?= true
-
-X:=
-SPACE:=$(X) $(X)
-
-.DEFAULT : all
-
-# Empty these to get rid of some default rules
-.SUFFIXES:
-.SUFFIXES: .java
-CO=
-GET=
-
-# Utilities used
-AWK       = awk
-CAT       = cat
-CD        = cd
-CHMOD     = chmod
-CP        = cp
-CUT       = cut
-DIRNAME   = dirname
-ECHO      = echo
-EGREP     = egrep
-EXPAND    = expand
-FIND      = find
-MKDIR     = mkdir
-PWD       = pwd
-RM        = rm -f
-SED       = sed
-SORT      = sort
-TEE       = tee
-UNAME     = uname
-UNIQ      = uniq
-WC        = wc
-ZIPEXE    = zip
-
-# Get OS name from uname (Cygwin inexplicably adds _NT-5.1)
-UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_)
-
-# Commands to run on paths to make mixed paths for java on windows
-ifeq ($(findstring CYGWIN,$(UNAME_S)), CYGWIN)
-  # Location of developer shared files
-  SLASH_JAVA = J:
-  GETMIXEDPATH = cygpath -m
-  PLATFORM = windows
-else
-  # Location of developer shared files
-  SLASH_JAVA = /java
-  GETMIXEDPATH = $(ECHO)
-  PLATFORM = unix # we only care about windows or bsd.
-  ifeq ($(UNAME_S), Darwin)
-    PLATFORM = bsd
-  endif
-  ifeq ($(findstring BSD,$(UNAME_S)), BSD)
-    PLATFORM = bsd
-  endif
-endif
-
-# convert list of directories to dos paths
-define MixedDirs
-$(foreach i,$1,$(shell $(GETMIXEDPATH) "${i}"))
-endef
-
-ifdef ALT_SLASH_JAVA
-  SLASH_JAVA = $(ALT_SLASH_JAVA)
-endif
-
-# Root of this test area (important to use full paths in some places)
-TEST_ROOT := $(shell $(PWD))
-
-# Root of all test results
-ifdef TEST_OUTPUT_DIR
-  $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg)
-  ABS_TEST_OUTPUT_DIR := \
-    $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD))
-else
-  ifdef ALT_OUTPUTDIR
-    ABS_OUTPUTDIR = $(shell $(CD) $(ALT_OUTPUTDIR) && $(PWD))
-  else
-    ABS_OUTPUTDIR = $(shell $(CD) $(TEST_ROOT)/.. && $(PWD))
-  endif
-
-  ABS_PLATFORM_BUILD_ROOT = $(ABS_OUTPUTDIR)
-  ABS_TEST_OUTPUT_DIR := $(ABS_PLATFORM_BUILD_ROOT)/testoutput/$(UNIQUE_DIR)
-endif
-
-# If unset, set up the PRODUCT_HOME variable to the jdk to test
-ifndef PRODUCT_HOME
-  # Try to use images/jdk if it exists
-  ABS_JDK_IMAGE = $(ABS_PLATFORM_BUILD_ROOT)/images/jdk
-  PRODUCT_HOME :=                               \
-    $(shell                                     \
-      if [ -d $(ABS_JDK_IMAGE) ] ; then         \
-         $(ECHO) "$(ABS_JDK_IMAGE)";            \
-       else                                     \
-         $(ECHO) "$(ABS_PLATFORM_BUILD_ROOT)";  \
-       fi)
-  PRODUCT_HOME := $(PRODUCT_HOME)
-endif
-
-# On Windows, setup the _NT_SYMBOL_PATH if possible.
-ifeq ($(PLATFORM), windows)
-  ifndef _NT_SYMBOL_PATH
-    ifdef PRODUCT_SYMBOLS_HOME
-      _NT_SYMBOL_PATH := \
-          $(subst $(SPACE),;,$(strip $(call MixedDirs, $(sort $(dir $(wildcard \
-          $(addprefix $(PRODUCT_SYMBOLS_HOME)/bin/, *.pdb */*.pdb)))))))
-      export _NT_SYMBOL_PATH
-    endif
-  endif
-  JTREG_BASIC_OPTIONS += -e:_NT_SYMBOL_PATH='$(_NT_SYMBOL_PATH)'
-endif
-
-ifneq ($(NATIVE_TEST_PATH), )
-  # jtreg -nativepath <dir>
-  #
-  # Local make tests will be TEST_IMAGE_DIR
-  ifdef TEST_IMAGE_DIR
-    TESTNATIVE_DIR = $(TEST_IMAGE_DIR)
-  endif
-  ifdef TESTNATIVE_DIR
-    JTREG_NATIVE_PATH = -nativepath:$(shell $(GETMIXEDPATH) "$(TESTNATIVE_DIR)/$(NATIVE_TEST_PATH)")
-  endif
-endif
-
-ifeq ($(USE_FAILURE_HANDLER), true)
-  # jtreg failure handler config
-  ifeq ($(FAILURE_HANDLER_DIR), )
-    ifneq ($(TESTNATIVE_DIR), )
-      FAILURE_HANDLER_DIR := $(TESTNATIVE_DIR)/failure_handler
-    endif
-  endif
-  ifneq ($(FAILURE_HANDLER_DIR), )
-    FAILURE_HANDLER_DIR_MIXED := $(shell $(GETMIXEDPATH) "$(FAILURE_HANDLER_DIR)")
-    JTREG_FAILURE_HANDLER_OPTIONS := \
-        -timeoutHandlerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
-        -observerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
-        -timeoutHandler:jdk.test.failurehandler.jtreg.GatherProcessInfoTimeoutHandler \
-        -observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver \
-        -timeoutHandlerTimeout:0
-  ifeq ($(PLATFORM), windows)
-      JTREG_FAILURE_HANDLER_OPTIONS += -J-Djava.library.path="$(FAILURE_HANDLER_DIR_MIXED)"
-    endif
-  endif
-endif
-
-# How to create the test bundle (pass or fail, we want to create this)
-#   Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed.
-ifneq ($(ARCHIVE_BUNDLE), )
-  ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`     \
-	           && $(CD) $(ABS_TEST_OUTPUT_DIR)             \
-	           && $(CHMOD) -R a+r . \
-	           && $(ZIPEXE) -q -r $(ARCHIVE_BUNDLE) . ) ;
-  CLEAN_ARCHIVE_BUNDLE = @$(RM) $(ARCHIVE_BUNDLE)
-endif
-
-# AddressSanitizer
-ifeq ($(ASAN_ENABLED), yes)
-  export ASAN_OPTIONS="handle_segv=0 detect_leaks=0"
-  JTREG_BASIC_OPTIONS += -e:ASAN_OPTIONS=$(ASAN_OPTIONS)
-  ifneq ($(DEVKIT_LIB_DIR),)
-    export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):$(DEVKIT_LIB_DIR)
-    JTREG_BASIC_OPTIONS += -e:LD_LIBRARY_PATH=$(LD_LIBRARY_PATH)
-  endif
-endif
-
-# important results files
-SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
-STATS_TXT_NAME = Stats.txt
-STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/$(STATS_TXT_NAME)")
-RUNLIST   = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/runlist.txt")
-PASSLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/passlist.txt")
-FAILLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/faillist.txt")
-EXITCODE  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/exitcode.txt")
-
-TESTEXIT = \
-  if [ ! -s $(EXITCODE) ] ; then \
-    $(ECHO) "ERROR: EXITCODE file not filled in."; \
-    $(ECHO) "1" > $(EXITCODE); \
-  fi ; \
-  testExitCode=`$(CAT) $(EXITCODE)`; \
-  $(ECHO) "EXIT CODE: $${testExitCode}"; \
-  exit $${testExitCode}
-
-ifeq ($(TREAT_EXIT_CODE_1_AS_0), true)
-  ADJUST_EXIT_CODE := \
-  if [ $${jtregExitCode} = 1 ] ; then \
-    jtregExitCode=0; \
-  fi
-else
-  # colon is the shell no-op
-  ADJUST_EXIT_CODE := :
-endif
-
-BUNDLE_UP_AND_EXIT = \
-( \
-  jtregExitCode=$$? && \
-  _summary="$(SUMMARY_TXT)"; \
-  $(ADJUST_EXIT_CODE) ; \
-  $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
-  $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
-  if [ -r "$${_summary}" ] ; then \
-    $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \
-    $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \
-    $(EGREP) ' Passed\.' $(RUNLIST) \
-      | $(EGREP) -v ' Error\.' \
-      | $(EGREP) -v ' Failed\.' > $(PASSLIST); \
-    ( $(EGREP) ' Failed\.' $(RUNLIST); \
-      $(EGREP) ' Error\.' $(RUNLIST); \
-      $(EGREP) -v ' Passed\.' $(RUNLIST) ) \
-      | $(SORT) | $(UNIQ) > $(FAILLIST); \
-    if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \
-      $(EXPAND) $(FAILLIST) \
-        | $(CUT) -d' ' -f1 \
-        | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \
-      if [ $${jtregExitCode} = 0 ] ; then \
-        jtregExitCode=1; \
-      fi; \
-    fi; \
-    runc="`$(CAT) $(RUNLIST)      | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    passc="`$(CAT) $(PASSLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    failc="`$(CAT) $(FAILLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    exclc="FIXME CODETOOLS-7900176"; \
-    $(ECHO) "TEST STATS: name=$(UNIQUE_DIR)  run=$${runc}  pass=$${passc}  fail=$${failc}" \
-      >> $(STATS_TXT); \
-  else \
-    $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \
-  fi; \
-  if [ -f $(STATS_TXT) ] ; then \
-    $(CAT) $(STATS_TXT); \
-  fi; \
-  $(ZIP_UP_RESULTS) \
-  $(TESTEXIT) \
-)
-
-################################################################
-
-# Prep for output
-# Change execute permissions on shared library files.
-# Files in repositories should never have execute permissions, but
-# there are some tests that have pre-built shared libraries, and these
-# windows dll files must have execute permission. Adding execute
-# permission may happen automatically on windows when using certain
-# versions of mercurial but it cannot be guaranteed. And blindly
-# adding execute permission might be seen as a mercurial 'change', so
-# we avoid adding execute permission to repository files. But testing
-# from a plain source tree needs the chmod a+rx. Applying the chmod to
-# all shared libraries not just dll files. And with CYGWIN and sshd
-# service, you may need CYGWIN=ntsec for this to work.
-prep:
-	@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
-	@if [ ! -d $(TEST_ROOT)/../../.hg ] && [ ! -d $(TEST_ROOT)/../../../.hg ]; then  \
-	  $(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \)  \
-	        -exec $(CHMOD) a+rx {} \; ;                                       \
-	fi
-
-ifeq ($(CLEAN_BEFORE_PREP), true)
-prep: clean
-
-endif
-
-# Cleanup
-clean:
-	@$(RM) -r $(ABS_TEST_OUTPUT_DIR)
-	$(CLEAN_ARCHIVE_BUNDLE)
-
-################################################################
-
-# jtreg tests
-
-# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
-ifndef JT_HOME
-  JT_HOME = $(SLASH_JAVA)/re/jtreg/$(USE_JTREG_VERSION)/promoted/latest/binaries/jtreg
-endif
-
-# Problematic tests to be excluded
-EXTRA_PROBLEM_LISTS :=
-PROBLEM_LISTS := ProblemList.txt $(EXTRA_PROBLEM_LISTS)
-
-# Create exclude list for this platform and arch
-ifdef NO_EXCLUDES
-  JTREG_EXCLUSIONS =
-else
-  JTREG_EXCLUSIONS = $(addprefix -exclude:, $(wildcard $(PROBLEM_LISTS)))
-endif
-
-# ------------------------------------------------------------------
-
-# The TESTDIRS variable can be used to select the jtreg tests to run
-ifdef TESTDIRS
-  TEST_SELECTION = $(TESTDIRS)
-endif
-
-ifeq ($(UNAME_S), SunOS)
-  NUM_CORES := $(shell LC_MESSAGES=C /usr/sbin/psrinfo -v | grep -c on-line)
-endif
-ifeq ($(UNAME_S), Linux)
-  NUM_CORES := $(shell cat /proc/cpuinfo  | grep -c processor)
-endif
-ifeq ($(UNAME_S), Darwin)
-  NUM_CORES := $(shell /usr/sbin/sysctl -n hw.ncpu)
-endif
-ifeq ($(findstring CYGWIN,$(UNAME_S)), CYGWIN)
-  ifneq ($(NUMBER_OF_PROCESSORS), )
-    NUM_CORES := $(NUMBER_OF_PROCESSORS)
-  else
-    ifneq ($(HOTSPOT_BUILD_JOBS), )
-      NUM_CORES := $(HOTSPOT_BUILD_JOBS)
-    else
-      NUM_CORES := 1 # fallback
-    endif
-  endif
-endif
-
-ifndef CONCURRENCY_FACTOR
-  CONCURRENCY_FACTOR = 1
-endif
-
-# Concurrency based on min(cores / 2, 12) * CONCURRENCY_FACTOR
-CONCURRENCY := $(shell $(AWK) \
-  'BEGIN { \
-    c = $(NUM_CORES) / 2; \
-    if (c > 12) c = 12; \
-    c = c * $(CONCURRENCY_FACTOR); \
-    if (c < 1) c = 1; \
-    printf "%.0f", c; \
-  }')
-JTREG_BASIC_OPTIONS += -concurrency:$(CONCURRENCY)
-
-# Make sure MaxRAMPercentage is low enough to not cause OOM or swapping since
-# we may end up with a lot of JVM's
-MAX_RAM_PERCENTAGE := $(shell expr 25 / $(CONCURRENCY))
-JTREG_BASIC_OPTIONS += -vmoption:-XX:MaxRAMPercentage=$(MAX_RAM_PERCENTAGE)
-
-ifdef EXTRA_JTREG_OPTIONS
-  JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
-endif
-
-# Default JTREG to run
-JTREG = $(JT_HOME)/bin/jtreg
-# run in agentvm/othervm mode
-JTREG_BASIC_OPTIONS += $(JTREG_VM_TYPE)
-# Only run automatic tests
-JTREG_BASIC_OPTIONS += -a
-# Always turn on assertions
-ifeq ($(USE_JTREG_ASSERT), true)
-  JTREG_ASSERT_OPTION = -ea -esa
-endif
-JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION)
-# jtreg verbosity setting
-# Default is to report details on all failed or error tests, times too
-JTREG_VERBOSE ?= fail,error,time
-JTREG_BASIC_OPTIONS += $(if $(JTREG_VERBOSE),-v:$(JTREG_VERBOSE))
-# Retain all files for failing tests
-JTREG_BASIC_OPTIONS += -retain:fail,error
-# Ignore tests are not run and completely silent about it
-JTREG_IGNORE_OPTION = -ignore:quiet
-JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
-# Multiply by 4 the timeout factor
-JTREG_TIMEOUT_OPTION =  -timeoutFactor:4
-JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
-ifeq ($(LIMIT_JTREG_VM_MEMORY), true)
-  # Set the max memory for jtreg control vm
-  JTREG_MEMORY_OPTION = -J-Xmx512m
-  JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION)
-  # Set the max memory for jtreg target test vms
-  JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx512m
-  JTREG_TEST_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
-endif
-# Make it possible to specify the JIB_DATA_DIR for tests using the
-# JIB Artifact resolver
-JTREG_BASIC_OPTIONS += -e:JIB_DATA_DIR
-# Give tests access to JT_JAVA, see JDK-8141609
-JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA}
-# Give aot tests access to Visual Studio installation
-ifneq ($(VS120COMNTOOLS), )
-  JTREG_BASIC_OPTIONS += -e:VS120COMNTOOLS="$(shell $(GETMIXEDPATH) "$(patsubst %\,%,$(VS120COMNTOOLS))")"
-endif
-
-JTREG_BASIC_OPTIONS += -e:TEST_IMAGE_GRAAL_DIR=${TEST_IMAGE_DIR}/hotspot/jtreg/graal
-
-# Set other vm and test options
-JTREG_TEST_OPTIONS += $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%)
-ifneq ($(JIB_HOME), )
-  JTREG_BASIC_OPTIONS += -e:JIB_HOME=$(shell $(GETMIXEDPATH) "$(JIB_HOME)")
-endif
-ifeq ($(IGNORE_MARKED_TESTS), true)
-  # Option to tell jtreg to not run tests marked with "ignore"
-  ifeq ($(PLATFORM), windows)
-    JTREG_KEY_OPTION = -k:!ignore
-  else
-    JTREG_KEY_OPTION = -k:\!ignore
-  endif
-  JTREG_BASIC_OPTIONS += $(JTREG_KEY_OPTION)
-endif
-
-# Make sure jtreg exists
-ifeq ($(USE_WINDOWS_EXISTENCE_CHECK), true)
-  jtreg_exists:
-	test -d $(shell $(GETMIXEDPATH) "$(JT_HOME)")
-	test -f $(shell $(GETMIXEDPATH) "$(JTREG)")
-
-else
-  jtreg_exists: $(JT_HOME)
-endif
-PHONY_LIST += jtreg_exists
-
-# Run jtreg
-jtreg_tests: prep jtreg_exists $(PRODUCT_HOME) $(TEST_PREREQS)
-	(                                                                    \
-	  ( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)");                   \
-	    export JT_HOME;                                                  \
-	    $(shell $(GETMIXEDPATH) "$(JTREG)")                              \
-	      $(JTREG_BASIC_OPTIONS)                                         \
-	      -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport")  \
-	      -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork")    \
-	      -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")                \
-	      $(JTREG_NATIVE_PATH)                                           \
-	      $(JTREG_FAILURE_HANDLER_OPTIONS)                               \
-	      $(JTREG_EXCLUSIONS)                                            \
-	      $(JTREG_TEST_OPTIONS)                                          \
-	      $(TEST_SELECTION)                                              \
-	  ) ;                                                                \
-	  $(BUNDLE_UP_AND_EXIT)                                              \
-	) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT)
-
-PHONY_LIST += jtreg_tests
-
-# Make it possible to call this with <component>_jtreg_tests
-%_jtreg_tests: jtreg_tests
-	# Must have a fake recipe here to prevent make from matching any other rule
-
-################################################################
-
-# Phony targets (e.g. these are not filenames)
-.PHONY: all clean prep $(PHONY_LIST)
-
-################################################################
--- a/test/hotspot/jtreg/Makefile	Thu Jan 24 17:11:10 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-#
-# Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-NATIVE_TEST_PATH := hotspot/jtreg/native
-
-CLEAN_BEFORE_PREP := true
-
-USE_JTREG_VERSION := 4.1
-
-USE_JTREG_ASSERT := false
-
-LIMIT_JTREG_VM_MEMORY := false
-
-IGNORE_MARKED_TESTS := true
-
-# Include the common base file with most of the logic
-include ../../TestCommon.gmk
-
-################################################################
-# Default make rule (runs jtreg_tests)
-all: hotspot_all
-	@$(ECHO) "Testing completed successfully"
-
-# Support "hotspot_" prefixed test make targets (too)
-# The hotspot_% targets are used by the top level Makefile
-# Unless explicitly defined below, hotspot_<x> is interpreted as a jtreg test group name
-hotspot_%:
-	$(ECHO) "Running tests: $@"
-	$(MAKE) -j 1 TEST_SELECTION=":$@" UNIQUE_DIR=$@ jtreg_tests;
-
-################################################################
-
-# Set up the directory in which the jvm directories live (client/, server/, etc.)
-ifeq ($(PLATFORM),windows)
-JVMS_DIR := $(PRODUCT_HOME)/bin
-else
-JVMS_DIR := $(PRODUCT_HOME)/lib
-endif
-
-# Use the existance of a directory as a sign that jvm variant is available
-CANDIDATE_JVM_VARIANTS := client minimal server
-JVM_VARIANTS := $(strip $(foreach x,$(CANDIDATE_JVM_VARIANTS),$(if $(wildcard $(JVMS_DIR)/$(x)),$(x))))
-
-################################################################
-
-# Run the native gtest tests from the test image
-
-define NEWLINE
-
-
-endef
-
-
-hotspot_gtest:
-	$(foreach v, $(JVM_VARIANTS), \
-	  $(MAKE) hotspot_gtest$v $(NEWLINE) )
-
-hotspot_gtestserver hotspot_gtestclient hotspot_gtestminimal: hotspot_gtest%:
-	$(TESTNATIVE_DIR)/hotspot/gtest/$*/gtestLauncher \
-	    -jdk $(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")
-
-PHONY_LIST += hotspot_gtest hotspot_gtestserver hotspot_gtestclient \
-    hotspot_gtestminimal
--- a/test/hotspot/jtreg/runtime/NMT/CheckForProperDetailStackTrace.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/test/hotspot/jtreg/runtime/NMT/CheckForProperDetailStackTrace.java	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, 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
@@ -42,7 +42,7 @@
     public static String stackTraceDefault =
         ".*Hashtable.*allocate_new_entry.*\n" +
         ".*ModuleEntryTable.*new_entry.*\n" +
-        ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" +
+        ".*ModuleEntryTable.*locked_create_entry.*\n" +
         ".*Modules.*define_module.*\n";
 
     /* The stack trace we look for on Solaris and Windows slowdebug builds. For some
@@ -50,12 +50,12 @@
     public static String stackTraceAllocateHeap =
         ".*AllocateHeap.*\n" +
         ".*ModuleEntryTable.*new_entry.*\n" +
-        ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" +
+        ".*ModuleEntryTable.*locked_create_entry.*\n" +
         ".*Modules.*define_module.*\n";
 
     /* A symbol that should always be present in NMT detail output. */
     private static String expectedSymbol =
-        "locked_create_entry_or_null";
+        "locked_create_entry";
 
     public static void main(String args[]) throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
--- a/test/jaxp/Makefile	Thu Jan 24 17:11:10 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#
-# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-default: all
-
-USE_JTREG_VERSION := 4.1
-
-include ../TestCommon.gmk
-
-# Default make rule (runs default JAXP tests)
-all: jaxp_all
-	@$(ECHO) "Testing completed successfully"
-
-# ------------------------------------------------------------------
-
-jaxp_%:
-	$(ECHO) "Running tests: $@"
-	for each in $@; do \
-	        $(MAKE) -j 1 TEST_SELECTION=":$$each" UNIQUE_DIR=$$each jtreg_tests; \
-	done
--- a/test/jdk/Makefile	Thu Jan 24 17:11:10 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#
-# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-default: all
-
-NATIVE_TEST_PATH := jdk/jtreg/native
-
-USE_FAILURE_HANDLER := true
-
-include ../TestCommon.gmk
-
-# Default make rule (runs default jdk tests)
-all: jdk_default
-	@$(ECHO) "Testing completed successfully"
-
-# ------------------------------------------------------------------
-
-jdk_% core_% svc_%:
-	$(ECHO) "Running tests: $@"
-	for each in $@; do \
-	        $(MAKE) -j 1 TEST_SELECTION=":$$each" UNIQUE_DIR=$$each jtreg_tests; \
-	done
--- a/test/jdk/java/net/Socks/SocksServer.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/test/jdk/java/net/Socks/SocksServer.java	Thu Jan 24 17:29:21 2019 +0000
@@ -24,7 +24,7 @@
 import java.io.*;
 import java.util.HashMap;
 
-public class SocksServer extends Thread {
+public class SocksServer extends Thread implements Closeable {
     // Some useful SOCKS constant
 
     static final int PROTO_VERS4        = 4;
@@ -503,7 +503,7 @@
         return port;
     }
 
-    public void terminate() {
+    public void close() {
         done = true;
         try { server.close(); } catch (IOException unused) {}
     }
--- a/test/jdk/java/net/Socks/SocksV4Test.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/test/jdk/java/net/Socks/SocksV4Test.java	Thu Jan 24 17:29:21 2019 +0000
@@ -26,36 +26,80 @@
  * @bug 4727547
  * @summary SocksSocketImpl throws NullPointerException
  * @build SocksServer
- * @run main SocksV4Test
+ * @run main/othervm SocksV4Test
  */
 
+import java.io.IOException;
 import java.net.*;
 
 public class SocksV4Test {
 
     // An unresolvable host
     static final String HOSTNAME = "doesnot.exist.invalid";
+    static final String USER = "johndoe";
+    static final String PASSWORD = "helloworld";
 
     public static void main(String[] args) throws Exception {
+        Authenticator.setDefault(new Auth());
+        UHETest();
+        getLocalPortTest();
+    }
+
+    static class Auth extends Authenticator {
+        protected PasswordAuthentication getPasswordAuthentication() {
+            return new PasswordAuthentication(USER, PASSWORD.toCharArray());
+        }
+    }
+
+    public static void getLocalPortTest() throws Exception {
+        // We actually use V5 for this test because that is the default
+        // protocol version used by the client and it doesn't really handle
+        // down grading very well.
+        try (SocksServer srvr = new SocksServer(0, false);
+             ServerSocket ss = new ServerSocket(0)) {
+
+            srvr.addUser(USER, PASSWORD);
+            int serverPort = ss.getLocalPort();
+            srvr.start();
+            int proxyPort = srvr.getPort();
+            System.out.printf("Server port %d, Proxy port %d\n", serverPort, proxyPort);
+            Proxy sp = new Proxy(Proxy.Type.SOCKS,
+                    new InetSocketAddress("localhost", proxyPort));
+            // Let's create an unresolved address
+            InetSocketAddress ad = new InetSocketAddress("127.0.0.1", serverPort);
+            try (Socket s = new Socket(sp)) {
+                s.connect(ad, 10000);
+                int pp = s.getLocalPort();
+                System.out.println("Local port = " + pp);
+                if (pp == serverPort || pp == proxyPort)
+                    throw new RuntimeException("wrong port returned");
+            } catch (UnknownHostException ex) {
+                throw new RuntimeException(ex);
+            } catch (IOException ioe) {
+                throw new RuntimeException(ioe);
+            }
+        }
+    }
+
+    public static void UHETest() throws Exception {
         // sanity before running the test
         assertUnresolvableHost(HOSTNAME);
 
         // Create a SOCKS V4 proxy
-        SocksServer srvr = new SocksServer(0, true);
-        srvr.start();
-        Proxy sp = new Proxy(Proxy.Type.SOCKS,
-                             new InetSocketAddress("localhost", srvr.getPort()));
-        // Let's create an unresolved address
-        InetSocketAddress ad = new InetSocketAddress(HOSTNAME, 1234);
-        try (Socket s = new Socket(sp)) {
-            s.connect(ad, 10000);
-        } catch (UnknownHostException ex) {
-            // OK, that's what we expected
-        } catch (NullPointerException npe) {
-            // Not OK, this used to be the bug
-            throw new RuntimeException("Got a NUllPointerException");
-        } finally {
-            srvr.terminate();
+        try (SocksServer srvr = new SocksServer(0, true)) {
+            srvr.start();
+            Proxy sp = new Proxy(Proxy.Type.SOCKS,
+                    new InetSocketAddress("localhost", srvr.getPort()));
+            // Let's create an unresolved address
+            InetSocketAddress ad = new InetSocketAddress(HOSTNAME, 1234);
+            try (Socket s = new Socket(sp)) {
+                s.connect(ad, 10000);
+            } catch (UnknownHostException ex) {
+                // OK, that's what we expected
+            } catch (NullPointerException npe) {
+                // Not OK, this used to be the bug
+                throw new RuntimeException("Got a NUllPointerException");
+            }
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/GZIPInputStreamTest.java	Thu Jan 24 17:29:21 2019 +0000
@@ -0,0 +1,650 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8217264
+ * @summary Tests that you can map an InputStream to a GZIPInputStream
+ * @library /test/lib http2/server
+ * @build jdk.test.lib.net.SimpleSSLContext
+ * @modules java.base/sun.net.www.http
+ *          java.net.http/jdk.internal.net.http.common
+ *          java.net.http/jdk.internal.net.http.frame
+ *          java.net.http/jdk.internal.net.http.hpack
+ * @run testng/othervm GZIPInputStreamTest
+ */
+
+import com.sun.net.httpserver.HttpServer;
+import com.sun.net.httpserver.HttpsConfigurator;
+import com.sun.net.httpserver.HttpsServer;
+import jdk.test.lib.net.SimpleSSLContext;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandler;
+import java.net.http.HttpResponse.BodyHandlers;
+import java.net.http.HttpResponse.BodySubscribers;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import static java.lang.System.out;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.testng.Assert.assertEquals;
+
+public class GZIPInputStreamTest implements HttpServerAdapters {
+
+    SSLContext sslContext;
+    HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
+    HttpTestServer httpsTestServer;   // HTTPS/1.1
+    HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
+    HttpTestServer https2TestServer;  // HTTP/2 ( h2  )
+    String httpURI;
+    String httpsURI;
+    String http2URI;
+    String https2URI;
+
+    static final int ITERATION_COUNT = 3;
+    // a shared executor helps reduce the amount of threads created by the test
+    // this test will block if the executor doesn't have at least two threads.
+    static final Executor executor = Executors.newFixedThreadPool(2);
+    static final Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
+
+    public static final String LOREM_IPSUM =
+            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
+                    + "Proin et lorem a sem faucibus finibus. "
+                    + "Nam nisl nibh, elementum laoreet rutrum quis, lobortis at sem. "
+                    + "Aenean purus libero, vehicula sed auctor ac, finibus commodo massa. "
+                    + "Etiam dapibus nisl ex, viverra iaculis sapien suscipit sit amet. "
+                    + "Phasellus fringilla id orci sit amet convallis. "
+                    + "Nam suscipit tempor felis sed feugiat. "
+                    + "Mauris quis viverra justo, vitae vulputate turpis. "
+                    + "Ut eu orci eget ante faucibus volutpat quis quis urna. "
+                    + "Ut porttitor mattis diam, ac sollicitudin ligula volutpat vel. "
+                    + "Quisque pretium leo sed augue lacinia, eu mollis dui tempor.\n\n"
+                    + "Nullam at mi porttitor, condimentum enim et, tristique felis. "
+                    + "Nulla ante elit, interdum id ante ac, dignissim suscipit urna. "
+                    + "Sed rhoncus felis eget placerat tincidunt. "
+                    + "Duis pellentesque, eros et laoreet lacinia, urna arcu elementum metus, "
+                    + "et tempor nibh ante vel odio. "
+                    + "Donec et dolor posuere, sagittis libero sit amet, imperdiet ligula. "
+                    + "Sed aliquam nulla congue bibendum hendrerit. "
+                    + "Morbi ut tincidunt turpis. "
+                    + "Nullam semper ipsum et sem imperdiet, sit amet commodo turpis euismod. "
+                    + "Nullam aliquet metus id libero elementum, ut pulvinar urna gravida. "
+                    + "Nullam non rhoncus diam. "
+                    + "Mauris sagittis bibendum odio, sed accumsan sem ullamcorper ut.\n\n"
+                    + "Proin malesuada nisl a quam dignissim rhoncus. "
+                    + "Pellentesque vitae dui velit. "
+                    + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
+                    + "Vivamus sagittis magna id magna vestibulum, nec lacinia odio maximus. "
+                    + "Nunc commodo, nisl non sagittis posuere, tortor ligula accumsan diam, "
+                    + "a rhoncus augue velit quis enim. "
+                    + "Nulla et dictum mauris. "
+                    + "Vivamus et accumsan mauris, et tincidunt nunc.\n\n"
+                    + "Nullam non pharetra lectus. "
+                    + "Fusce lobortis sapien ante, quis egestas tellus tincidunt efficitur. "
+                    + "Proin tempus mollis urna, sit amet congue diam eleifend in. "
+                    + "Ut auctor metus ipsum, at porta turpis consectetur sed. "
+                    + "Ut malesuada euismod massa, ut elementum nisi mattis eget. "
+                    + "Donec ultrices vel dolor at convallis. "
+                    + "Nunc eget felis nec nunc faucibus finibus. "
+                    + "Curabitur nec auctor metus, sit amet tristique lorem. "
+                    + "Donec tempus fringilla suscipit. Cras sit amet ante elit. "
+                    + "Ut sodales sagittis eros quis cursus. "
+                    + "Maecenas finibus ante quis euismod rutrum. "
+                    + "Aenean scelerisque placerat nisi. "
+                    + "Fusce porta, nibh vel efficitur sodales, urna eros consequat tellus, "
+                    + "at fringilla ex justo in mi. "
+                    + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
+                    + "Morbi accumsan, justo nec tincidunt pretium, justo ex consectetur ante, "
+                    + "nec euismod diam velit vitae quam.\n\n"
+                    + "Vestibulum ante ipsum primis in faucibus orci luctus et "
+                    + "ultrices posuere cubilia Curae; "
+                    + "Praesent eget consequat nunc, vel dapibus nulla. "
+                    + "Maecenas egestas luctus consectetur. "
+                    + "Duis lacus risus, sollicitudin sit amet justo sed, "
+                    + "ultrices facilisis sapien. "
+                    + "Mauris eget fermentum risus. "
+                    + "Suspendisse potenti. Nam at tempor risus. "
+                    + "Quisque lacus augue, dictum vel interdum quis, interdum et mi. "
+                    + "In purus mauris, pellentesque et lectus eget, condimentum pretium odio."
+                    + " Donec imperdiet congue laoreet. "
+                    + "Cras pharetra hendrerit purus ac efficitur. \n";
+
+
+
+    @DataProvider(name = "variants")
+    public Object[][] variants() {
+        return new Object[][]{
+                { httpURI,   false },
+                { httpURI,   true },
+                { httpsURI,  false },
+                { httpsURI,  true },
+                { http2URI,  false },
+                { http2URI,  true },
+                { https2URI, false },
+                { https2URI, true },
+        };
+    }
+
+    final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
+    HttpClient newHttpClient() {
+        return TRACKER.track(HttpClient.newBuilder()
+                         .executor(executor)
+                         .sslContext(sslContext)
+                         .build());
+    }
+
+    HttpClient newSingleThreadClient() {
+        return TRACKER.track(HttpClient.newBuilder()
+                .executor(singleThreadExecutor)
+                .sslContext(sslContext)
+                .build());
+    }
+
+    HttpClient newInLineClient() {
+        return TRACKER.track(HttpClient.newBuilder()
+                .executor((r) -> r.run() )
+                .sslContext(sslContext)
+                .build());
+    }
+
+    @Test(dataProvider = "variants")
+    public void testPlainSyncAsString(String uri, boolean sameClient) throws Exception {
+        out.println("\nSmoke test: verify that the result we get from the server is correct.");
+        out.println("Uses plain send() and `asString` to get the plain string.");
+        out.println("Uses single threaded executor");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newSingleThreadClient(); // should work with 1 single thread
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri +"/txt/LoremIpsum.txt"))
+                    .build();
+            BodyHandler<String> handler = BodyHandlers.ofString(UTF_8);
+            HttpResponse<String> response = client.send(req, handler);
+            String lorem = response.body();
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    @Test(dataProvider = "variants")
+    public void testPlainSyncAsInputStream(String uri, boolean sameClient) throws Exception {
+        out.println("Uses plain send() and `asInputStream` - calls readAllBytes() from main thread");
+        out.println("Uses single threaded executor");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newSingleThreadClient(); // should work with 1 single thread
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri + "/txt/LoremIpsum.txt"))
+                    .build();
+            BodyHandler<InputStream> handler = BodyHandlers.ofInputStream();
+            HttpResponse<InputStream> response = client.send(req, handler);
+            String lorem = new String(response.body().readAllBytes(), UTF_8);
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    @Test(dataProvider = "variants")
+    public void testGZIPSyncAsInputStream(String uri, boolean sameClient) throws Exception {
+        out.println("Uses plain send() and `asInputStream` - " +
+                "creates GZIPInputStream and calls readAllBytes() from main thread");
+        out.println("Uses single threaded executor");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newSingleThreadClient(); // should work with 1 single thread
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri + "/gz/LoremIpsum.txt.gz"))
+                    .build();
+            BodyHandler<InputStream> handler = BodyHandlers.ofInputStream();
+            HttpResponse<InputStream> response = client.send(req, handler);
+            GZIPInputStream gz = new GZIPInputStream(response.body());
+            String lorem = new String(gz.readAllBytes(), UTF_8);
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    @Test(dataProvider = "variants")
+    public void testGZIPSyncAsGZIPInputStream(String uri, boolean sameClient) throws Exception {
+        out.println("Uses plain send() and a mapping subscriber to "+
+                "create the GZIPInputStream. Calls readAllBytes() from main thread");
+        out.println("Uses a fixed thread pool executor with 2 thread");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newHttpClient(); // needs at least 2 threads
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri + "/gz/LoremIpsum.txt.gz"))
+                    .build();
+            // This is dangerous, because the finisher will block.
+            // We support this, but the executor must have enough threads.
+            BodyHandler<InputStream> handler = new GZIPBodyHandler();
+            HttpResponse<InputStream> response = client.send(req, handler);
+            String lorem = new String(response.body().readAllBytes(), UTF_8);
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    @Test(dataProvider = "variants")
+    public void testGZIPSyncAsGZIPInputStreamSupplier(String uri, boolean sameClient) throws Exception {
+        out.println("Uses plain send() and a mapping subscriber to "+
+                "create a Supplier<GZIPInputStream>. Calls Supplier.get() " +
+                "and readAllBytes() from main thread");
+        out.println("Uses a single threaded executor");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newSingleThreadClient(); // should work with 1 single thread
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri + "/gz/LoremIpsum.txt.gz"))
+                    .build();
+            // This is dangerous, because the finisher will block.
+            // We support this, but the executor must have enough threads.
+            BodyHandler<Supplier<InputStream>> handler = new BodyHandler<Supplier<InputStream>>() {
+                 public HttpResponse.BodySubscriber<Supplier<InputStream>> apply(
+                         HttpResponse.ResponseInfo responseInfo)
+                 {
+                    String contentType = responseInfo.headers().firstValue("Content-Encoding")
+                            .orElse("identity");
+                    out.println("Content-Encoding: " + contentType);
+                    if (contentType.equalsIgnoreCase("gzip")) {
+                        // This is dangerous. Blocking in the mapping function can wedge the
+                        // response. We do support it provided that there enough thread in
+                        // the executor.
+                        return BodySubscribers.mapping(BodySubscribers.ofInputStream(),
+                                (is) -> (() -> {
+                                    try {
+                                        return new GZIPInputStream(is);
+                                    } catch (IOException io) {
+                                        throw new UncheckedIOException(io);
+                                    }
+                                }));
+                    } else return BodySubscribers.mapping(BodySubscribers.ofInputStream(),
+                            (is) -> (() -> is));
+                }
+            };
+            HttpResponse<Supplier<InputStream>> response = client.send(req, handler);
+            String lorem = new String(response.body().get().readAllBytes(), UTF_8);
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    @Test(dataProvider = "variants")
+    public void testPlainAsyncAsInputStreamBlocks(String uri, boolean sameClient) throws Exception {
+        out.println("Uses sendAsync() and `asInputStream`. Registers a dependent action "+
+                "that calls readAllBytes()");
+        out.println("Uses a fixed thread pool executor with two threads");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newHttpClient(); // needs at least 2 threads
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri + "/txt/LoremIpsum.txt"))
+                    .build();
+            BodyHandler<InputStream> handler = BodyHandlers.ofInputStream();
+            CompletableFuture<HttpResponse<InputStream>> responseCF = client.sendAsync(req, handler);
+            // This is dangerous. Blocking in the mapping function can wedge the
+            // response. We do support it provided that there enough threads in
+            // the executor.
+            String lorem = responseCF.thenApply((r) -> {
+                try {
+                    return new String(r.body().readAllBytes(), UTF_8);
+                } catch (IOException io) {
+                    throw new UncheckedIOException(io);
+                }
+            }).join();
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    @Test(dataProvider = "variants")
+    public void testGZIPAsyncAsGZIPInputStreamBlocks(String uri, boolean sameClient) throws Exception {
+        out.println("Uses sendAsync() and a mapping subscriber to create a GZIPInputStream. " +
+                 "Registers a dependent action that calls readAllBytes()");
+        out.println("Uses a fixed thread pool executor with two threads");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newHttpClient(); // needs at least 2 threads
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri + "/gz/LoremIpsum.txt.gz"))
+                    .build();
+            BodyHandler<InputStream> handler = new GZIPBodyHandler();
+            CompletableFuture<HttpResponse<InputStream>> responseCF = client.sendAsync(req, handler);
+            // This is dangerous - we support this, but it can block
+            // if there are not enough threads available.
+            // Correct custom code should use thenApplyAsync instead.
+            String lorem = responseCF.thenApply((r) -> {
+                try {
+                    return new String(r.body().readAllBytes(), UTF_8);
+                } catch (IOException io) {
+                    throw new UncheckedIOException(io);
+                }
+            }).join();
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    @Test(dataProvider = "variants")
+    public void testGZIPSyncAsGZIPInputStreamBlocks(String uri, boolean sameClient) throws Exception {
+        out.println("Uses sendAsync() and a mapping subscriber to create a GZIPInputStream," +
+                "which is mapped again using a mapping subscriber " +
+                "to call readAllBytes() and map to String");
+        out.println("Uses a fixed thread pool executor with two threads");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newHttpClient(); // needs at least 2 threads
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri + "/gz/LoremIpsum.txt.gz"))
+                    .build();
+            // This is dangerous. Blocking in the mapping function can wedge the
+            // response. We do support it provided that there enough thread in
+            // the executor.
+            BodyHandler<String> handler = new MappingBodyHandler<>(new GZIPBodyHandler(),
+                    (InputStream is) ->  {
+                        try {
+                            return new String(is.readAllBytes(), UTF_8);
+                        } catch(IOException io) {
+                            throw new UncheckedIOException(io);
+                        }
+                    });
+            HttpResponse<String> response = client.send(req, handler);
+            String lorem = response.body();
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    @Test(dataProvider = "variants")
+    public void testGZIPSyncAsGZIPInputStreamSupplierInline(String uri, boolean sameClient) throws Exception {
+        out.println("Uses plain send() and a mapping subscriber to "+
+                "create a Supplier<GZIPInputStream>. Calls Supplier.get() " +
+                "and readAllBytes() from main thread");
+        out.println("Uses an inline executor (no threads)");
+        HttpClient client = null;
+        for (int i=0; i< ITERATION_COUNT; i++) {
+            if (!sameClient || client == null)
+                client = newInLineClient(); // should even work with no threads
+
+            HttpRequest req = HttpRequest.newBuilder(URI.create(uri + "/gz/LoremIpsum.txt.gz"))
+                    .build();
+            // This is dangerous, because the finisher will block.
+            // We support this, but the executor must have enough threads.
+            BodyHandler<Supplier<InputStream>> handler = new BodyHandler<Supplier<InputStream>>() {
+                public HttpResponse.BodySubscriber<Supplier<InputStream>> apply(
+                        HttpResponse.ResponseInfo responseInfo)
+                {
+                    String contentType = responseInfo.headers().firstValue("Content-Encoding")
+                            .orElse("identity");
+                    out.println("Content-Encoding: " + contentType);
+                    if (contentType.equalsIgnoreCase("gzip")) {
+                        // This is dangerous. Blocking in the mapping function can wedge the
+                        // response. We do support it provided that there enough thread in
+                        // the executor.
+                        return BodySubscribers.mapping(BodySubscribers.ofInputStream(),
+                                (is) -> (() -> {
+                                    try {
+                                        return new GZIPInputStream(is);
+                                    } catch (IOException io) {
+                                        throw new UncheckedIOException(io);
+                                    }
+                                }));
+                    } else return BodySubscribers.mapping(BodySubscribers.ofInputStream(),
+                            (is) -> (() -> is));
+                }
+            };
+            HttpResponse<Supplier<InputStream>> response = client.send(req, handler);
+            String lorem = new String(response.body().get().readAllBytes(), UTF_8);
+            if (!LOREM_IPSUM.equals(lorem)) {
+                out.println("Response doesn't match");
+                out.println("[" + LOREM_IPSUM + "] != [" + lorem + "]");
+                assertEquals(LOREM_IPSUM, lorem);
+            } else {
+                out.println("Received expected response.");
+            }
+        }
+    }
+
+    static final class GZIPBodyHandler implements BodyHandler<InputStream> {
+        @Override
+        public HttpResponse.BodySubscriber<InputStream> apply(HttpResponse.ResponseInfo responseInfo) {
+            String contentType = responseInfo.headers().firstValue("Content-Encoding")
+                    .orElse("identity");
+            out.println("Content-Encoding: " + contentType);
+            if (contentType.equalsIgnoreCase("gzip")) {
+                // This is dangerous. Blocking in the mapping function can wedge the
+                // response. We do support it provided that there enough thread in
+                // the executor.
+                return BodySubscribers.mapping(BodySubscribers.ofInputStream(),
+                        (is) -> {
+                    try {
+                        return new GZIPInputStream(is);
+                    } catch (IOException io) {
+                        throw new UncheckedIOException(io);
+                    }
+                });
+            } else return BodySubscribers.ofInputStream();
+        }
+    }
+
+    static final class MappingBodyHandler<T,U> implements BodyHandler<U> {
+        final BodyHandler<T> upstream;
+        final Function<? super T,? extends U> finisher;
+        MappingBodyHandler(BodyHandler<T> upstream, Function<T,U> finisher) {
+            this.upstream = upstream;
+            this.finisher = finisher;
+        }
+        @Override
+        public HttpResponse.BodySubscriber<U> apply(HttpResponse.ResponseInfo responseInfo) {
+            return BodySubscribers.mapping(upstream.apply(responseInfo), finisher);
+        }
+    }
+
+    static String serverAuthority(HttpServer server) {
+        return InetAddress.getLoopbackAddress().getHostName() + ":"
+                + server.getAddress().getPort();
+    }
+
+    @BeforeTest
+    public void setup() throws Exception {
+        sslContext = new SimpleSSLContext().get();
+        if (sslContext == null)
+            throw new AssertionError("Unexpected null sslContext");
+
+        HttpTestHandler plainHandler = new LoremIpsumPlainHandler();
+        HttpTestHandler gzipHandler  = new LoremIpsumGZIPHandler();
+
+        // HTTP/1.1
+        InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
+        httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0));
+        httpTestServer.addHandler(plainHandler, "/http1/chunk/txt");
+        httpTestServer.addHandler(gzipHandler,  "/http1/chunk/gz");
+        httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/chunk";
+
+        HttpsServer httpsServer = HttpsServer.create(sa, 0);
+        httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));
+        httpsTestServer = HttpTestServer.of(httpsServer);
+        httpsTestServer.addHandler(plainHandler, "/https1/chunk/txt");
+        httpsTestServer.addHandler(gzipHandler, "/https1/chunk/gz");
+        httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/chunk";
+
+        // HTTP/2
+        http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0));
+        http2TestServer.addHandler(plainHandler, "/http2/chunk/txt");
+        http2TestServer.addHandler(gzipHandler, "/http2/chunk/gz");
+        http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/chunk";
+
+        https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext));
+        https2TestServer.addHandler(plainHandler, "/https2/chunk/txt");
+        https2TestServer.addHandler(gzipHandler, "/https2/chunk/gz");
+        https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/chunk";
+
+        httpTestServer.start();
+        httpsTestServer.start();
+        http2TestServer.start();
+        https2TestServer.start();
+    }
+
+    @AfterTest
+    public void teardown() throws Exception {
+        Thread.sleep(100);
+        AssertionError fail = TRACKER.check(500);
+        try {
+            httpTestServer.stop();
+            httpsTestServer.stop();
+            http2TestServer.stop();
+            https2TestServer.stop();
+        } finally {
+            if (fail != null) {
+                throw fail;
+            }
+        }
+    }
+
+
+    static class LoremIpsumPlainHandler implements HttpTestHandler {
+        @Override
+        public void handle(HttpTestExchange t) throws IOException {
+            try {
+                out.println("LoremIpsumPlainHandler received request to " + t.getRequestURI());
+                t.getResponseHeaders().addHeader("Content-Encoding", "identity");
+                t.sendResponseHeaders(200, -1);
+                long size = 0;
+                try (OutputStream os = t.getResponseBody()) {
+                    for (String s : LOREM_IPSUM.split("\n")) {
+                        byte[] buf = s.getBytes(StandardCharsets.UTF_8);
+                        System.out.println("Writing " + (buf.length + 1) + " bytes...");
+                        os.write(buf);
+                        os.write('\n');
+                        os.flush();
+                        size += buf.length + 1;
+                    }
+                } finally {
+                    System.out.println("Sent " + size + " bytes");
+                }
+            } catch (IOException | RuntimeException | Error e) {
+                e.printStackTrace();
+                throw e;
+            }
+        }
+    }
+
+    static class LoremIpsumGZIPHandler implements HttpTestHandler {
+        @Override
+        public void handle(HttpTestExchange t) throws IOException {
+            try {
+                out.println("LoremIpsumGZIPHandler received request to " + t.getRequestURI());
+                t.getResponseHeaders().addHeader("Content-Encoding", "gzip");
+                t.sendResponseHeaders(200, -1);
+                long size = 0;
+                try (GZIPOutputStream os =
+                             new GZIPOutputStream(t.getResponseBody())) {
+                    for (String s : LOREM_IPSUM.split("\n")) {
+                        byte[] buf = s.getBytes(StandardCharsets.UTF_8);
+                        System.out.println("Writing and compressing "
+                                + (buf.length + 1) + " uncompressed bytes...");
+                        os.write(buf);
+                        os.write('\n');
+                        os.flush();
+                        size += buf.length + 1;
+                    }
+                } finally {
+                    System.out.println("Sent and compressed " + size + " uncompressed bytes");
+                }
+            } catch (IOException | RuntimeException | Error e) {
+                e.printStackTrace();
+                throw e;
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/Base64/TestEncodingDecodingLength.java	Thu Jan 24 17:29:21 2019 +0000
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.ByteBuffer;
+import java.util.Base64;
+
+/**
+ * @test
+ * @bug 8210583
+ * @summary Tests Base64.Encoder.encode/Decoder.decode for the large size
+ *          of resulting bytes which can not be allocated
+ * @requires os.maxMemory >= 6g
+ * @run main/othervm -Xms4g -Xmx6g TestEncodingDecodingLength
+ *
+ */
+
+public class TestEncodingDecodingLength {
+
+    public static void main(String[] args) {
+        int size = Integer.MAX_VALUE - 2;
+        byte[] inputBytes = new byte[size];
+        byte[] outputBytes = new byte[size];
+
+        // Check encoder with large array length
+        Base64.Encoder encoder = Base64.getEncoder();
+        checkOOM("encode(byte[])", () -> encoder.encode(inputBytes));
+        checkIAE("encode(byte[] byte[])", () -> encoder.encode(inputBytes, outputBytes));
+        checkOOM("encodeToString(byte[])", () -> encoder.encodeToString(inputBytes));
+        checkOOM("encode(ByteBuffer)", () -> encoder.encode(ByteBuffer.allocate(size)));
+
+        // Check decoder with large array length
+        Base64.Decoder decoder = Base64.getDecoder();
+        checkOOM("decode(byte[])", () -> decoder.decode(inputBytes));
+        checkIAE("decode(byte[], byte[])", () -> decoder.decode(inputBytes, outputBytes));
+        checkOOM("decode(ByteBuffer)", () -> decoder.decode(ByteBuffer.allocate(size)));
+    }
+
+    private static final void checkOOM(String methodName, Runnable r) {
+        try {
+            r.run();
+            throw new RuntimeException("OutOfMemoryError should have been thrown by: " + methodName);
+        } catch (OutOfMemoryError er) {}
+    }
+
+    private static final void checkIAE(String methodName, Runnable r) {
+        try {
+            r.run();
+            throw new RuntimeException("IllegalArgumentException should have been thrown by: " + methodName);
+        } catch (IllegalArgumentException iae) {}
+    }
+}
+
--- a/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java	Thu Jan 24 17:29:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -73,6 +73,8 @@
         },
     };
 
+    private static final String NO_INHERITANCE_MARKER = "\u2205\u2205\u2205";
+
     public static void main(String[] args) {
         // Make sure that localized time zone names of CLDR are used
         // if specified.
@@ -131,5 +133,27 @@
         if (errors > 0) {
             throw new RuntimeException("test failed");
         }
+
+        // 8217366: No "no inheritance marker" should be left in the returned array
+        // from DateFormatSymbols.getZoneStrings()
+        List.of(Locale.ROOT,
+                Locale.CHINA,
+                Locale.GERMANY,
+                Locale.JAPAN,
+                Locale.UK,
+                Locale.US,
+                Locale.forLanguageTag("hi-IN"),
+                Locale.forLanguageTag("es-419")).stream()
+            .peek(System.out::println)
+            .map(l -> DateFormatSymbols.getInstance(l).getZoneStrings())
+            .flatMap(zoneStrings -> Arrays.stream(zoneStrings))
+            .filter(namesArray -> Arrays.stream(namesArray)
+                .anyMatch(aName -> aName.equals(NO_INHERITANCE_MARKER)))
+            .findAny()
+            .ifPresentOrElse(marker -> {
+                    throw new RuntimeException("No inheritance marker detected with tzid: "
+                                                + marker[0]);
+                },
+                () -> System.out.println("Success: No \"no inheritance marker\" detected."));
     }
 }
--- a/test/jdk/sun/net/www/protocol/http/ProxyTunnelServer.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/test/jdk/sun/net/www/protocol/http/ProxyTunnelServer.java	Thu Jan 24 17:29:21 2019 +0000
@@ -38,33 +38,40 @@
 
 public class ProxyTunnelServer extends Thread {
 
-    private static ServerSocket ss = null;
+    private final ServerSocket ss;
     /*
      * holds the registered user's username and password
      * only one such entry is maintained
      */
-    private String userPlusPass;
+    private volatile String userPlusPass;
 
     // client requesting for a tunnel
-    private Socket clientSocket = null;
+    private volatile Socket clientSocket = null;
 
     /*
      * Origin server's address and port that the client
      * wants to establish the tunnel for communication.
      */
-    private InetAddress serverInetAddr;
-    private int serverPort;
+    private volatile InetAddress serverInetAddr;
+    private volatile int serverPort;
 
     /*
      * denote whether the proxy needs to authorize
      * CONNECT requests.
      */
-    static boolean needAuth = false;
+
+    volatile boolean needAuth = false;
 
     public ProxyTunnelServer() throws IOException {
-        if (ss == null) {
-          ss = (ServerSocket) ServerSocketFactory.getDefault().
-          createServerSocket(0);
+        ss = new ServerSocket(0);
+    }
+
+    static private void close(Closeable c) {
+        try {
+            if (c != null)
+                c.close();
+        } catch (IOException e) {
+            e.printStackTrace();
         }
     }
 
@@ -72,6 +79,11 @@
         needAuth = auth;
     }
 
+    public void terminate() {
+        close(ss);
+        close(clientSocket);
+    }
+
     /*
      * register users with the proxy, by providing username and
      * password. The username and password are used for authorizing the
@@ -81,10 +93,16 @@
         userPlusPass = uname + ":" + passwd;
     }
 
+    volatile boolean makeTunnel;
+
+    public void doTunnel(boolean tunnel) {
+        makeTunnel = tunnel;
+    }
+
     public void run() {
         try {
             clientSocket = ss.accept();
-            processRequests();
+            processRequests(makeTunnel);
         } catch (Exception e) {
             System.out.println("Proxy Failed: " + e);
             e.printStackTrace();
@@ -105,7 +123,7 @@
      * if there is a match, connection is set in tunneling mode. If
      * needAuth is set to false, Proxy-Authorization checks are not made
      */
-    private void processRequests() throws Exception {
+    private void processRequests(boolean makeTunnel) throws Exception {
 
         InputStream in = clientSocket.getInputStream();
         MessageHeader mheader = new MessageHeader(in);
@@ -125,6 +143,13 @@
                    }
                 }
             }
+
+            if (makeTunnel) {
+                retrieveConnectInfo(statusLine);
+                doTunnel();
+                return;
+            }
+
             respondForConnect(needAuth);
 
             // connection set to the tunneling mode
@@ -178,6 +203,9 @@
      * direction.
      */
     private void doTunnel() throws Exception {
+        OutputStream out = clientSocket.getOutputStream();
+        out.write("HTTP/1.1 200 OK\r\n\r\n".getBytes());
+        out.flush();
 
         Socket serverSocket = new Socket(serverInetAddr, serverPort);
         ProxyTunnel clientToServer = new ProxyTunnel(
@@ -202,10 +230,10 @@
      * socket, until both sockets are open and EOF has not been received.
      */
     class ProxyTunnel extends Thread {
-        Socket sockIn;
-        Socket sockOut;
-        InputStream input;
-        OutputStream output;
+        final Socket sockIn;
+        final Socket sockOut;
+        final InputStream input;
+        final OutputStream output;
 
         public ProxyTunnel(Socket sockIn, Socket sockOut)
         throws Exception {
--- a/test/jdk/sun/net/www/protocol/http/TunnelThroughProxy.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/test/jdk/sun/net/www/protocol/http/TunnelThroughProxy.java	Thu Jan 24 17:29:21 2019 +0000
@@ -25,6 +25,7 @@
  * @test
  * @bug 4620362
  * @modules java.base/sun.net.www
+ * @build ProxyTunnelServer
  * @run main/othervm TunnelThroughProxy
  * @summary JSSE not returning proper exception on unknown host
  */
@@ -34,8 +35,13 @@
 
 public class TunnelThroughProxy {
     public static void main(String[] args) throws Exception {
+        nonexistingHostTest();
+        getLocalPortTest();
+    }
+
+    static void nonexistingHostTest() throws Exception {
+        ProxyTunnelServer proxy = setupProxy(false);
         try {
-            setupProxy();
             URL u = new URL("https://www.nonexistent-site.com/");
             URLConnection uc = u.openConnection();
             InputStream is = uc.getInputStream();
@@ -44,16 +50,48 @@
             if (!e.getMessage().matches(".*HTTP\\/.*500.*")) {
                 throw new RuntimeException(e);
             }
+        } finally {
+            proxy.terminate();
         }
     }
-    static void setupProxy() throws IOException {
+
+
+    static void getLocalPortTest() throws Exception {
+        ProxyTunnelServer proxy = setupProxy(true);
+        try {
+            int proxyPort = proxy.getPort();
+            ServerSocket server = new ServerSocket(0);
+            int serverPort = server.getLocalPort();
+
+            Socket sock;
+            sock = new Socket(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", proxyPort)));
+            InetSocketAddress dest = new InetSocketAddress("127.0.0.1", serverPort);
+            sock.connect(dest);
+            int localPort = sock.getLocalPort();
+            if (localPort == proxyPort)
+                throw new RuntimeException("Fail: socket has wrong local port");
+            // check that tunnel really works
+            Socket sock1 = server.accept();
+            OutputStream os = sock1.getOutputStream();
+            os.write(99);
+            os.flush();
+            if (sock.getInputStream().read() != 99)
+                throw new RuntimeException("Tunnel does not work");
+        } finally {
+            proxy.terminate();
+        }
+    }
+
+    static ProxyTunnelServer setupProxy(boolean makeTunnel) throws IOException {
         ProxyTunnelServer pserver = new ProxyTunnelServer();
+        pserver.doTunnel(makeTunnel);
+        int proxyPort = pserver.getPort();
 
         // disable proxy authentication
         pserver.needUserAuth(false);
         pserver.start();
         System.setProperty("https.proxyHost", "localhost");
-        System.setProperty("https.proxyPort", String.valueOf(
-                                        pserver.getPort()));
+        System.setProperty("https.proxyPort", String.valueOf(proxyPort));
+        return pserver;
     }
 }
--- a/test/langtools/Makefile	Thu Jan 24 17:11:10 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,464 +0,0 @@
-#
-# Makefile to run jtreg and other tests
-#
-
-# Product builds and langtools builds
-#
-# A full product build (or "control" build) creates a complete JDK image.
-# To test a product build, set TESTJAVA to the path for the image.
-#
-# A langtools build just builds the langtools components of a JDK.
-# To test a langtools build, set TESTJAVA to the path for a recent JDK
-# build, and set TESTBOOTCLASSPATH to the compiled langtools classes --
-# for example build/classes or dist/lib/classes.jar.
-
-# Get OS/ARCH specifics
-OSNAME = $(shell uname -s)
-ifeq ($(OSNAME), SunOS)
-  SLASH_JAVA = /java
-  PLATFORM = solaris
-  ARCH = $(shell uname -p)
-  ifeq ($(ARCH), i386)
-    ARCH=i586
-  endif
-endif
-ifeq ($(OSNAME), Linux)
-  SLASH_JAVA = /java
-  PLATFORM = linux
-  ARCH = $(shell uname -m)
-  ifeq ($(ARCH), i386)
-    ARCH=i586
-  endif
-endif
-ifeq ($(OSNAME), Darwin)
-  PLATFORM = bsd
-  ARCH = $(shell uname -m)
-  ifeq ($(ARCH), i386)
-    ARCH=i586
-  endif
-endif
-ifeq ($(OSNAME), Windows_NT)
-  # MKS
-  PLATFORM=windows
-endif
-ifeq ($(PLATFORM),)
-  PLATFORM = windows
-  CYGPATH = | cygpath -m -s -f -
-endif
-
-ifeq ($(PLATFORM), windows)
-  SLASH_JAVA = J:
-  ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64)
-    ARCH=ia64
-  else
-    ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),AMD64)
-      ARCH=x64
-    else
-      ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),EM64T)
-        ARCH=x64
-      else
-        ARCH=i586
-      endif
-    endif
-  endif
-  EXE_SUFFIX=.exe
-endif
-
-# Root of this test area (important to use full paths in some places)
-TEST_ROOT := $(shell pwd $(CYGPATH) )
-
-ifeq ($(PLATFORM), windows)
-  SLASH_JAVA = J:
-else
-  SLASH_JAVA = /java
-endif
-
-# Default JTREG to run
-ifndef JTREG_HOME
-  ifdef JT_HOME
-    JTREG_HOME = $(JT_HOME)
-  else
-    JTREG_HOME = $(SLASH_JAVA)/re/jtreg/4.2/promoted/latest/
-  endif
-endif
-JTREG = $(JTREG_HOME)/bin/jtreg
-JTDIFF = $(JTREG_HOME)/bin/jtdiff
-
-# Problematic tests to be excluded
-PROBLEM_LISTS=ProblemList.txt
-
-# Create exclude list for this platform and arch
-ifdef NO_EXCLUDES
-  JTREG_EXCLUSIONS =
-else
-  JTREG_EXCLUSIONS = $(PROBLEM_LISTS:%=-exclude:%)
-endif
-
-# Default JCK to run
-ifndef JCK_HOME
-  JCK_HOME = $(SLASH_JAVA)/re/jck/8/promoted/latest/binaries
-endif
-
-# Default JDK for JTREG and JCK
-#
-# JT_JAVA is the version of java used to run jtreg/JCK. 
-#
-ifndef JT_JAVA
-  JT_JAVA = $(SLASH_JAVA)/re/jdk/1.9.0/archive/fcs/binaries/$(PLATFORM)-$(ARCH)
-endif
-
-# Default JDK to test
-TESTJAVA = $(SLASH_JAVA)/re/jdk/1.9.0/promoted/latest/binaries/$(PLATFORM)-$(ARCH)
-
-# PRODUCT_HOME is a variable pointing to a directory containing the output from
-# make/Makefile
-# For langtools, this is a directory containing build and dist
-# For a control build, this is build/$(PRODUCT)-$(ARCH)/XYZ-image
-#	(i.e, j2sdk-image or jdk-module-image)
-ifdef PRODUCT_HOME
-  ifeq ($(shell [ -r $(PRODUCT_HOME)/dist/lib/classes.jar ]; echo $$?),0)
-    TESTBOOTCLASSPATH = $(PRODUCT_HOME)/dist/lib/classes.jar
-  endif
-  ifeq ($(shell [ -r $(PRODUCT_HOME)/bin/javac$(EXE_SUFFIX) ]; echo $$?),0)
-    TESTJAVA = $(PRODUCT_HOME)
-  endif
-endif
-
-ifdef TESTBOOTCLASSPATH
-  JTREG_OPTIONS += -Xbootclasspath/p:$(TESTBOOTCLASSPATH)
-### In the following, -refvmoptions is an undocumented option
-### The following does not work JCK 7 b30 2/6/2010. Awaiting b31.
-  JCK_OPTIONS += \
-	-vmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH) \
-	-refvmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH)
-endif
-
-# Set the max memory for jtreg target test JVMs
-JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx768m
-JTREG_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
-
-# Retain all files for failing tests
-JTREG_OPTIONS += -retain:fail,error
-
-ifdef EXTRA_JTREG_OPTIONS
-  JTREG_OPTIONS += $(EXTRA_JTREG_OPTIONS)
-endif
-
-# Concurrency is the number of tests that can execute at once.
-# On an otherwise empty machine, suggest setting to (#cpus + 2)
-# If unset, the default is (#cpus)
-### RFE: determine and use #cpus
-ifdef CONCURRENCY
-  JTREG_OPTIONS += -agentvm -concurrency:$(CONCURRENCY)
-else
-  JTREG_OPTIONS += -agentvm
-endif
-
-ifdef JCK_CONCURRENCY
-  JCK_OPTIONS += -concurrency:$(JCK_CONCURRENCY)
-endif
-
-# JCK is executed using "Multi-JVM Group Mode", which is a hybrid
-# of otherVM and sameVM modes. New JVMs are created and reused for
-# a number of tests, then eventually discarded and a new one started.
-# This amortizes the JVM startup time.  The "group size" defines
-# how many tests are run in a JVM before it is replaced.
-# If unset, the default is 100.
-JCK_GROUP_SIZE = 1000
-ifdef JCK_GROUP_SIZE
-  JCK_COMPILER_OPTIONS += \
-    -jtoptions:-Ejck.env.compiler.testCompile.groupMode.groupSize=$(JCK_GROUP_SIZE) \
-    -jtoptions:-Ejck.env.compiler.compRefExecute.groupMode.groupSize=$(JCK_GROUP_SIZE)
-### The following is not supported. Awaiting RFE 6924287
-### 6924287: Jck4Jdk: Allow to configure test group size for group mode via simple command line option
-###  JCK_RUNTIME_OPTIONS += \
-###    -jtoptions:-Ejck.env.runtime.testCompile.groupMode.groupSize=$(JCK_GROUP_SIZE)
-endif
-
-# Timeouts
-ifdef JTREG_TIMEOUT_FACTOR
-  JTREG_OPTIONS += -timeoutFactor:$(JTREG_TIMEOUT_FACTOR)
-endif
-
-ifdef JCK_TIMEOUT_FACTOR
-  JCK_OPTIONS += -timeout:$(JCK_TIMEOUT_FACTOR)
-endif
-
-# Default verbosity setting for jtreg
-JTREG_VERBOSE ?= fail,error,time
-
-# Default verbosity setting for jck
-JCK_VERBOSE ?= non-pass
-
-# Assertions: some tests show failures when assertions are enabled.
-# Since javac is typically loaded via the bootclassloader (either via TESTJAVA
-# or TESTBOOTCLASSPATH), you may need -esa to enable assertions in javac.
-JTREG_OPTIONS += $(ASSERTION_OPTIONS)
-JCK_OPTIONS += $(ASSERTION_OPTIONS:%=-vmoptions:%)
-
-# Include shared options
-JCK_COMPILER_OPTIONS += $(JCK_OPTIONS)
-JCK_RUNTIME_OPTIONS += $(JCK_OPTIONS)
-
-# Exit codes:
-# jtreg, jck:   0: OK, 1: tests failed, 2: tests error; 3+: SERIOUS
-FATAL_JTREG_EXIT = 3
-FATAL_JCK_EXIT = 3
-# jtdiff: 0: OK, 1: differences found; 2+: SERIOUS
-FATAL_JTDIFF_EXIT = 2
-#
-# Exit -- used for final "normal" exit from "make". Redefine to "true" to avoid
-# having make exit with non-zero return code.
-EXIT = exit
-# Function to exit shell if exit code of preceding command is greater than or equal
-# to a given level. Redefine function or preceding FATAL_*_EXIT codes as needed.
-EXIT_IF_FATAL = status=$$?; if [ $$status -ge $(1) ]; then exit $$status ; fi
-
-# Root of all test results
-TEST_OUTPUT_DIR ?= $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)/test/langtools
-ABS_TEST_OUTPUT_DIR := \
-	$(shell mkdir -p $(TEST_OUTPUT_DIR); \
-		cd  $(TEST_OUTPUT_DIR); \
-		pwd $(CYGPATH))
-# Subdirectories for different test runs
-JTREG_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jtreg
-JCK_COMPILER_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-compiler
-JCK_RUNTIME_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-runtime-Xcompile
-
-# Is the test JVM 32-bit?
-DATA_MODEL := \
-	$(shell $(TESTJAVA)/bin/java -XshowSettings:properties -version 2>&1 | \
-		grep 'sun\.arch\.data\.model' | \
-		awk '{print $$3}')
-ifeq ($(DATA_MODEL), 32)
-  # Set the GC options for test vms having a smaller address space
-  JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
-  JTREG_OPTIONS += $(JTREG_GC_OPTION)
-endif
-
-# Default make rule -- warning, may take a while
-all: jtreg-tests jck-compiler-tests jck-runtime-tests all-summary
-	@echo "Testing completed successfully"
-
-jtreg apt javac javadoc javah javap jdeps: jtreg-tests jtreg-summary
-	@echo "Testing completed successfully"
-
-jck-compiler: jck-compiler-tests jck-compiler-summary
-	@echo "Testing completed successfully"
-
-jck-runtime: jck-runtime-tests jck-runtime-summary
-	@echo "Testing completed successfully"
-
-# a way to select tests from outside
-# works for targets 'jtreg', 'jck-compiler', and 'jck-runtime'
-ifdef TEST_SELECTION
-  JTREG_TESTDIRS = $(TEST_SELECTION)
-  JCK_COMPILER_TESTDIRS = $(TEST_SELECTION)
-  JCK_RUNTIME_TESTDIRS = $(TEST_SELECTION)
-endif
-
-# convenience targets
-all:		JTREG_TESTDIRS = .
-jtreg:		JTREG_TESTDIRS ?= .
-apt:		JTREG_TESTDIRS = tools/apt
-javac: 		JTREG_TESTDIRS = tools/javac
-javadoc:	JTREG_TESTDIRS = tools/javadoc com/sun/javadoc
-javah:		JTREG_TESTDIRS = tools/javah
-javap:		JTREG_TESTDIRS = tools/javap
-jdeps:		JTREG_TESTDIRS = tools/jdeps
-
-
-# Run jtreg tests
-#
-# JTREG_HOME
-#	Installed location of jtreg
-# JT_JAVA
-#	Version of java used to run jtreg.  Should normally be the same as TESTJAVA
-# TESTJAVA
-# 	Version of java to be tested.
-# JTREG_VERBOSE
-# Verbosity setting for jtreg
-# JTREG_OPTIONS
-#	Additional options for jtreg
-# JTREG_TESTDIRS
-#	Directories of tests to be run
-# JTREG_OUTPUT_DIR
-#	Where to write the results
-# JTREG_REFERENCE
-#	(Optional) reference results (e.g. work, report or summary.txt)
-#
-jtreg_tests: jtreg-tests
-jtreg-tests: check-jtreg FRC
-	@rm -f -r $(JTREG_OUTPUT_DIR)/JTwork $(JTREG_OUTPUT_DIR)/JTreport \
-	    $(JTREG_OUTPUT_DIR)/diff.html $(JTREG_OUTPUT_DIR)/status.txt
-	@mkdir -p $(JTREG_OUTPUT_DIR)
-	( JT_JAVA=$(JT_JAVA) $(JTREG) \
-	  -a -ignore:quiet $(if $(JTREG_VERBOSE),-v:$(JTREG_VERBOSE)) \
-	  -r:$(JTREG_OUTPUT_DIR)/JTreport \
-	  -w:$(JTREG_OUTPUT_DIR)/JTwork \
-	  -jdk:$(TESTJAVA) \
-	  $(JAVA_ARGS:%=-vmoption:%) \
-	  $(JTREG_EXCLUSIONS) \
-	  $(JTREG_OPTIONS) \
-	  $(JTREG_TESTDIRS) \
-	  || ( $(call EXIT_IF_FATAL,$(FATAL_JTREG_EXIT)) ; \
-	    echo $$status > $(JTREG_OUTPUT_DIR)/status.txt \
-	  ) \
-	) 2>&1 | tee $(JTREG_OUTPUT_DIR)/output.txt
-ifdef JTREG_REFERENCE
-	JT_JAVA=$(JT_JAVA) $(JTDIFF) -o $(JTREG_OUTPUT_DIR)/diff.html \
-	    $(JTREG_REFERENCE) $(JTREG_OUTPUT_DIR)/JTreport \
-	|| ( $(call EXIT_IF_FATAL,$(FATAL_JTDIFF_EXIT)) )
-endif
-
-jtreg-summary: FRC
-	@if [ -r $(JTREG_OUTPUT_DIR)/status.txt ]; then \
-	    echo ; echo "Summary of jtreg test failures" ; \
-	    cat $(JTREG_OUTPUT_DIR)/JTreport/text/summary.txt | \
-		grep -v 'Not run' | grep -v 'Passed' ; \
-	    echo ; \
-	    $(EXIT) `cat $(JTREG_OUTPUT_DIR)/status.txt` ; \
-	fi
-
-# Check to make sure these directories exist
-check-jtreg: $(PRODUCT_HOME) $(JTREG)
-
-
-# Run JCK-compiler tests
-#
-# JCK_HOME
-#	Installed location of JCK: should include JCK-compiler, and JCK-extras
-#       Default is JCK 8.
-# JT_JAVA
-#	Version of java used to run JCK.  Should normally be the same as TESTJAVA
-#       Default is JDK 7
-# TESTJAVA
-# 	Version of java to be tested.
-# JCK_VERBOSE
-#	Verbosity setting for jtjck
-# JCK_COMPILER_OPTIONS
-#	Additional options for JCK-compiler
-# JCK_COMPILER_TESTDIRS
-#	Directories of tests to be run
-# JCK_COMPILER_OUTPUT_DIR
-#	Where to write the results
-# JCK_COMPILER_REFERENCE
-#	(Optional) reference results (e.g. work, report or summary.txt)
-#
-jck-compiler-tests: check-jck FRC
-	@rm -f -r $(JCK_COMPILER_OUTPUT_DIR)/work $(JCK_COMPILER_OUTPUT_DIR)/report \
-	    $(JCK_COMPILER_OUTPUT_DIR)/diff.html $(JCK_COMPILER_OUTPUT_DIR)/status.txt
-	@mkdir -p $(JCK_COMPILER_OUTPUT_DIR)
-	$(JT_JAVA)/bin/java -Xmx1024m \
-	    -jar $(JCK_HOME)/JCK-compiler-9/lib/jtjck.jar \
-	    $(if $(JCK_VERBOSE),$(if $(filter $(JCK_VERBOSE),summary),-v,-v:$(JCK_VERBOSE))) \
-            -r:$(JCK_COMPILER_OUTPUT_DIR)/report \
-            -w:$(JCK_COMPILER_OUTPUT_DIR)/work \
-            -jdk:$(TESTJAVA) \
-	    $(JCK_COMPILER_OPTIONS) \
-            $(JCK_COMPILER_TESTDIRS) \
-	|| ( $(call EXIT_IF_FATAL,$(FATAL_JCK_EXIT)) ; \
-	    echo $$status > $(JCK_COMPILER_OUTPUT_DIR)/status.txt \
-	)
-ifdef JCK_COMPILER_REFERENCE
-	JT_JAVA=$(JT_JAVA) $(JTDIFF) -o $(JCK_COMPILER_OUTPUT_DIR)/diff.html \
-	    $(JCK_COMPILER_REFERENCE) $(JCK_COMPILER_OUTPUT_DIR)/report \
-	|| ( $(call EXIT_IF_FATAL,$(FATAL_JTDIFF_EXIT)) )
-endif
-
-jck-compiler-summary: FRC
-	@if [ -r $(JCK_COMPILER_OUTPUT_DIR)/status.txt ]; then \
-	    echo ; echo "Summary of JCK-compiler test failures" ; \
-	    cat $(JCK_COMPILER_OUTPUT_DIR)/report/text/summary.txt | \
-		grep -v 'Not run' | grep -v 'Passed' ; \
-	    echo ; \
-	    $(EXIT) `cat $(JCK_COMPILER_OUTPUT_DIR)/status.txt` ; \
-	fi
-
-# Run JCK-runtime tests in -Xcompile mode
-# This is a special mode to test javac by compiling the tests in the JCK-runtime test suite
-# Normal JCK-runtime invocation belongs in the jdk/ repository.
-#
-# JCK_HOME
-#	Installed location of JCK: should include JCK-compiler, JCK-runtime and JCK-extras
-# JT_JAVA
-#	Version of java used to run JCK.  Should normally be the same as TESTJAVA
-# TESTJAVA
-# 	Version of java to be tested.
-# JCK_VERBOSE
-#	Verbosity setting for jtjck
-# JCK_RUNTIME_OPTIONS
-#	Additional options for JCK-runtime
-# JCK_RUNTIME_TESTDIRS
-#	Directories of tests to be run
-# JCK_RUNTIME_OUTPUT_DIR
-#	Where to write the results
-# JCK_RUNTIME_REFERENCE
-#	(Optional) reference results (e.g. work, report or summary.txt)
-#
-jck-runtime-tests: check-jck FRC
-	@rm -f -r $(JCK_RUNTIME_OUTPUT_DIR)/work $(JCK_RUNTIME_OUTPUT_DIR)/report \
-	    $(JCK_RUNTIME_OUTPUT_DIR)/diff.html $(JCK_RUNTIME_OUTPUT_DIR)/status.txt
-	@mkdir -p $(JCK_RUNTIME_OUTPUT_DIR)
-	$(JT_JAVA)/bin/java -Xmx1024m \
-	    -jar $(JCK_HOME)/JCK-runtime-9/lib/jtjck.jar \
-	    $(if $(JCK_VERBOSE),$(if $(filter $(JCK_VERBOSE),summary),-v,-v:$(JCK_VERBOSE))) \
-            -r:$(JCK_RUNTIME_OUTPUT_DIR)/report \
-            -w:$(JCK_RUNTIME_OUTPUT_DIR)/work \
-            -jdk:$(TESTJAVA) \
-	    -Xcompile \
-	    $(JCK_RUNTIME_OPTIONS) \
-            $(JCK_RUNTIME_TESTDIRS) \
-	|| ( $(call EXIT_IF_FATAL,$(FATAL_JCK_EXIT)) ; \
-	    echo $$status > $(JCK_RUNTIME_OUTPUT_DIR)/status.txt \
-	)
-ifdef JCK_RUNTIME_REFERENCE
-	JT_JAVA=$(JT_JAVA) $(JTDIFF) -o $(JCK_RUNTIME_OUTPUT_DIR)/diff.html \
-	    $(JCK_RUNTIME_REFERENCE) $(JCK_RUNTIME_OUTPUT_DIR)/report \
-	|| ( $(call EXIT_IF_FATAL,$(FATAL_JTDIFF_EXIT)) )
-endif
-
-jck-runtime-summary: FRC
-	@if [ -r $(JCK_RUNTIME_OUTPUT_DIR)/status.txt ]; then \
-	    echo ; echo "Summary of JCK-runtime test failures" ; \
-	    cat $(JCK_RUNTIME_OUTPUT_DIR)/report/text/summary.txt | \
-		grep -v 'Not run' | grep -v 'Passed' ; \
-	    echo ; \
-	    $(EXIT) `cat $(JCK_RUNTIME_OUTPUT_DIR)/status.txt` ; \
-	fi
-
-# Check to make sure these directories exist
-check-jck:
-	@if [ ! -d '$(JCK_HOME)' ]; then \
-	    echo "JCK_HOME $(JCK_HOME) missing" ; \
-	    $(EXIT) 1 ; \
-	fi
-	@if [ ! -d '$(PRODUCT_HOME)' ]; then \
-	    echo "PRODUCT_HOME $(PRODUCT_HOME) missing" ; \
-	    $(EXIT) 1 ; \
-	fi
-
-all-summary: FRC
-	@if [ -n "`find $(TEST_OUTPUT_DIR) -name status.txt`" ]; then
-	    echo ; echo "Summary of test failures" ; \
-	    cat `find $(TEST_OUTPUT_DIR) -name summary.txt` | \
-		grep -v 'Not run' | grep -v 'Passed' ; \
-	    echo ; \
-	    $(EXIT) 1
-	fi
-
-# Cleanup
-clean:
-
-# Used to force a target rules to run
-FRC:
-
-# Phony targets (e.g. these are not filenames)
-.PHONY: all clean \
-	jtreg javac javadoc javah javap jdeps jtreg-tests jtreg-summary check-jtreg \
-	jck-compiler jck-compiler-tests jck-compiler-summary \
-	jck-runtime jck-runtime-tests jck-runtime-summary check-jck
-
-# No use of suffix rules
-.SUFFIXES:
-
--- a/test/micro/org/openjdk/bench/javax/crypto/full/CryptoBase.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/full/CryptoBase.java	Thu Jan 24 17:29:21 2019 +0000
@@ -45,7 +45,7 @@
 import java.util.concurrent.TimeUnit;
 
 
-@Fork(5)
+@Fork(jvmArgsAppend = {"-XX:+AlwaysPreTouch"}, value = 5)
 @Warmup(iterations = 3, time = 3)
 @Measurement(iterations = 8, time = 2)
 @OutputTimeUnit(TimeUnit.SECONDS)
--- a/test/micro/org/openjdk/bench/vm/lang/LockUnlock.java	Thu Jan 24 17:11:10 2019 +0000
+++ b/test/micro/org/openjdk/bench/vm/lang/LockUnlock.java	Thu Jan 24 17:29:21 2019 +0000
@@ -110,6 +110,18 @@
         factorial = fact(10);
     }
 
+    /**
+     * Same as {@link #testRecursiveSynchronization()} but the first call
+     * to this method will generate the identity hashcode for this object
+     * which effectively disables biased locking as they occupy the same
+     * bits in the object header.
+     */
+    @Benchmark
+    public void testRecursiveSynchronizationNoBias() {
+        System.identityHashCode(this);
+        factorial = fact(10);
+    }
+
     private synchronized int fact(int n) {
         if (n == 0) {
             return 1;
--- a/test/nashorn/Makefile	Thu Jan 24 17:11:10 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#
-# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-default: all
-
-USE_FAILURE_HANDLER := true
-
-include ../TestCommon.gmk
-
-# Default make rule (runs default nashorn tests)
-all: nashorn_default
-	@$(ECHO) "Testing completed successfully"
-
-# ------------------------------------------------------------------
-
-nashorn_%:
-	$(ECHO) "Running tests: $@"
-	for each in $@; do \
-	        $(MAKE) -j 1 TEST_SELECTION=":$$each" UNIQUE_DIR=$$each jtreg_tests; \
-	done
-