Merge JDK-8200758-branch
authorherrick
Tue, 01 Oct 2019 23:54:39 -0400
branchJDK-8200758-branch
changeset 58437 a44c029e85db
parent 58435 788704ff2559 (current diff)
parent 58436 91d236715160 (diff)
child 58455 0d95b41d0895
Merge
--- a/make/autoconf/basics.m4	Tue Oct 01 18:53:13 2019 -0400
+++ b/make/autoconf/basics.m4	Tue Oct 01 23:54:39 2019 -0400
@@ -213,8 +213,10 @@
   if test "x[$]$1" != x; then
     new_path="[$]$1"
 
-    if [ [[ "$new_path" = ~* ]] ]; then
-      # Use eval to expand a potential ~
+    # Use eval to expand a potential ~. This technique does not work if there
+    # are spaces in the path (which is valid at this point on Windows), so only
+    # try to apply it if there is an actual ~ first in the path.
+    if [ [[ "$new_path" = "~"* ]] ]; then
       eval new_path="$new_path"
       if test ! -f "$new_path" && test ! -d "$new_path"; then
         AC_MSG_ERROR([The new_path of $1, which resolves as "$new_path", is not found.])
--- a/src/hotspot/cpu/x86/assembler_x86.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -4742,6 +4742,25 @@
   emit_int8((unsigned char)0xA5);
 }
 
+void Assembler::roundsd(XMMRegister dst, XMMRegister src, int32_t rmode) {
+  assert(VM_Version::supports_sse4_1(), "");
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+  emit_int8(0x0B);
+  emit_int8((unsigned char)(0xC0 | encode));
+  emit_int8((unsigned char)rmode);
+}
+
+void Assembler::roundsd(XMMRegister dst, Address src, int32_t rmode) {
+  assert(VM_Version::supports_sse4_1(), "");
+  InstructionMark im(this);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+  emit_int8(0x0B);
+  emit_operand(dst, src);
+  emit_int8((unsigned char)rmode);
+}
+
 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
@@ -5539,6 +5558,49 @@
   emit_operand(dst, src);
 }
 
+void Assembler::vroundpd(XMMRegister dst, XMMRegister src, int32_t rmode, int vector_len) {
+  assert(VM_Version::supports_avx(), "");
+  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+  emit_int8(0x09);
+  emit_int8((unsigned char)(0xC0 | encode));
+  emit_int8((unsigned char)(rmode));
+}
+
+void Assembler::vroundpd(XMMRegister dst, Address src, int32_t rmode,  int vector_len) {
+  assert(VM_Version::supports_avx(), "");
+  InstructionMark im(this);
+  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
+  vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+  emit_int8(0x09);
+  emit_operand(dst, src);
+  emit_int8((unsigned char)(rmode));
+}
+
+void Assembler::vrndscalepd(XMMRegister dst,  XMMRegister src,  int32_t rmode, int vector_len) {
+  assert(VM_Version::supports_evex(), "requires EVEX support");
+  InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+  attributes.set_is_evex_instruction();
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+  emit_int8((unsigned char)0x09);
+  emit_int8((unsigned char)(0xC0 | encode));
+  emit_int8((unsigned char)(rmode));
+}
+
+void Assembler::vrndscalepd(XMMRegister dst, Address src, int32_t rmode, int vector_len) {
+  assert(VM_Version::supports_evex(), "requires EVEX support");
+  assert(dst != xnoreg, "sanity");
+  InstructionMark im(this);
+  InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+  attributes.set_is_evex_instruction();
+  attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
+  vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+  emit_int8((unsigned char)0x09);
+  emit_operand(dst, src);
+  emit_int8((unsigned char)(rmode));
+}
+
+
 void Assembler::vsqrtpd(XMMRegister dst, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
   InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
--- a/src/hotspot/cpu/x86/assembler_x86.hpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp	Tue Oct 01 23:54:39 2019 -0400
@@ -1856,6 +1856,9 @@
   void sqrtsd(XMMRegister dst, Address src);
   void sqrtsd(XMMRegister dst, XMMRegister src);
 
+  void roundsd(XMMRegister dst, Address src, int32_t rmode);
+  void roundsd(XMMRegister dst, XMMRegister src, int32_t rmode);
+
   // Compute Square Root of Scalar Single-Precision Floating-Point Value
   void sqrtss(XMMRegister dst, Address src);
   void sqrtss(XMMRegister dst, XMMRegister src);
@@ -2020,6 +2023,12 @@
   void vsqrtps(XMMRegister dst, XMMRegister src, int vector_len);
   void vsqrtps(XMMRegister dst, Address src, int vector_len);
 
+  // Round Packed Double precision value.
+  void vroundpd(XMMRegister dst, XMMRegister src, int32_t rmode, int vector_len);
+  void vroundpd(XMMRegister dst, Address src, int32_t rmode, int vector_len);
+  void vrndscalepd(XMMRegister dst,  XMMRegister src,  int32_t rmode, int vector_len);
+  void vrndscalepd(XMMRegister dst, Address src, int32_t rmode, int vector_len);
+
   // Bitwise Logical AND of Packed Floating-Point Values
   void andpd(XMMRegister dst, XMMRegister src);
   void andps(XMMRegister dst, XMMRegister src);
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -3661,6 +3661,15 @@
   }
 }
 
+void MacroAssembler::roundsd(XMMRegister dst, AddressLiteral src, int32_t rmode, Register scratch_reg) {
+  if (reachable(src)) {
+    Assembler::roundsd(dst, as_Address(src), rmode);
+  } else {
+    lea(scratch_reg, src);
+    Assembler::roundsd(dst, Address(scratch_reg, 0), rmode);
+  }
+}
+
 void MacroAssembler::subss(XMMRegister dst, AddressLiteral src) {
   if (reachable(src)) {
     Assembler::subss(dst, as_Address(src));
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Tue Oct 01 23:54:39 2019 -0400
@@ -1180,6 +1180,10 @@
   void sqrtsd(XMMRegister dst, Address src)        { Assembler::sqrtsd(dst, src); }
   void sqrtsd(XMMRegister dst, AddressLiteral src);
 
+  void roundsd(XMMRegister dst, XMMRegister src, int32_t rmode)    { Assembler::roundsd(dst, src, rmode); }
+  void roundsd(XMMRegister dst, Address src, int32_t rmode)        { Assembler::roundsd(dst, src, rmode); }
+  void roundsd(XMMRegister dst, AddressLiteral src, int32_t rmode, Register scratch_reg);
+
   void sqrtss(XMMRegister dst, XMMRegister src)    { Assembler::sqrtss(dst, src); }
   void sqrtss(XMMRegister dst, Address src)        { Assembler::sqrtss(dst, src); }
   void sqrtss(XMMRegister dst, AddressLiteral src);
--- a/src/hotspot/cpu/x86/x86.ad	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/cpu/x86/x86.ad	Tue Oct 01 23:54:39 2019 -0400
@@ -1485,6 +1485,10 @@
         ret_value = false;
       }
       break;
+    case Op_RoundDoubleMode:
+      if (UseSSE < 4)
+         ret_value = false;
+      break;
   }
 
   return ret_value;  // Per default match rules are supported.
@@ -1536,6 +1540,10 @@
         if (vlen != 4)
           ret_value  = false;
         break;
+      case Op_RoundDoubleModeV:
+        if (VM_Version::supports_avx() == false)
+          ret_value = false;
+        break;
     }
   }
 
@@ -2854,6 +2862,108 @@
   ins_pipe(pipe_slow);
 %}
 
+
+instruct roundD_reg(legRegD dst, legRegD src, immU8 rmode) %{
+  predicate(UseSSE>=4);
+  match(Set dst (RoundDoubleMode src rmode));
+  format %{ "roundsd  $dst, $src" %}
+  ins_cost(150);
+  ins_encode %{
+    __ roundsd($dst$$XMMRegister, $src$$XMMRegister, $rmode$$constant);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
+instruct roundD_mem(legRegD dst, memory src, immU8 rmode) %{
+  predicate(UseSSE>=4);
+  match(Set dst (RoundDoubleMode (LoadD src) rmode));
+  format %{ "roundsd  $dst, $src" %}
+  ins_cost(150);
+  ins_encode %{
+    __ roundsd($dst$$XMMRegister, $src$$Address, $rmode$$constant);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
+instruct roundD_imm(legRegD dst, immD con, immU8 rmode, rRegI scratch_reg) %{
+  predicate(UseSSE>=4);
+  match(Set dst (RoundDoubleMode con rmode));
+  effect(TEMP scratch_reg);
+  format %{ "roundsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
+  ins_cost(150);
+  ins_encode %{
+    __ roundsd($dst$$XMMRegister, $constantaddress($con), $rmode$$constant, $scratch_reg$$Register);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
+instruct vround2D_reg(legVecX dst, legVecX src, immU8 rmode) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (RoundDoubleModeV src rmode));
+  format %{ "vroundpd  $dst, $src, $rmode\t! round packed2D" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vroundpd($dst$$XMMRegister, $src$$XMMRegister, $rmode$$constant, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vround2D_mem(legVecX dst, memory mem, immU8 rmode) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (RoundDoubleModeV (LoadVector mem) rmode));
+  format %{ "vroundpd $dst, $mem, $rmode\t! round packed2D" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vroundpd($dst$$XMMRegister, $mem$$Address, $rmode$$constant, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vround4D_reg(legVecY dst, legVecY src, legVecY rmode) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (RoundDoubleModeV src rmode));
+  format %{ "vroundpd  $dst, $src, $rmode\t! round packed4D" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vroundpd($dst$$XMMRegister, $src$$XMMRegister, $rmode$$constant, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vround4D_mem(legVecY dst, memory mem, immU8 rmode) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (RoundDoubleModeV (LoadVector mem) rmode));
+  format %{ "vroundpd $dst, $mem, $rmode\t! round packed4D" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vroundpd($dst$$XMMRegister, $mem$$Address, $rmode$$constant, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+
+instruct vround8D_reg(vecZ dst, vecZ src, immU8 rmode) %{
+  predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
+  match(Set dst (RoundDoubleModeV src rmode));
+  format %{ "vrndscalepd $dst, $src, $rmode\t! round packed8D" %}
+  ins_encode %{
+    int vector_len = 2;
+    __ vrndscalepd($dst$$XMMRegister, $src$$XMMRegister, $rmode$$constant, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vround8D_mem(vecZ dst, memory mem, immU8 rmode) %{
+  predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
+  match(Set dst (RoundDoubleModeV (LoadVector mem) rmode));
+  format %{ "vrndscalepd $dst, $mem, $rmode\t! round packed8D" %}
+  ins_encode %{
+    int vector_len = 2;
+    __ vrndscalepd($dst$$XMMRegister, $mem$$Address, $rmode$$constant, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
 instruct onspinwait() %{
   match(OnSpinWait);
   ins_cost(200);
--- a/src/hotspot/os/windows/os_windows.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/os/windows/os_windows.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -4159,128 +4159,137 @@
   }
 }
 
-// The following function is adapted from java.base/windows/native/libjava/canonicalize_md.c
-// Creates an UNC path from a single byte path. Return buffer is
-// allocated in C heap and needs to be freed by the caller.
-// Returns NULL on error.
-static wchar_t* create_unc_path(const char* path, errno_t &err) {
-  wchar_t* wpath = NULL;
-  size_t converted_chars = 0;
-  size_t path_len = strlen(path) + 1; // includes the terminating NULL
-  if (path[0] == '\\' && path[1] == '\\') {
-    if (path[2] == '?' && path[3] == '\\'){
-      // if it already has a \\?\ don't do the prefix
-      wpath = (wchar_t*)os::malloc(path_len * sizeof(wchar_t), mtInternal);
-      if (wpath != NULL) {
-        err = ::mbstowcs_s(&converted_chars, wpath, path_len, path, path_len);
+// Returns the given path as an absolute wide path in unc format. The returned path is NULL
+// on error (with err being set accordingly) and should be freed via os::free() otherwise.
+// additional_space is the number of additionally allocated wchars after the terminating L'\0'.
+// This is based on pathToNTPath() in io_util_md.cpp, but omits the optimizations for
+// short paths.
+static wchar_t* wide_abs_unc_path(char const* path, errno_t & err, int additional_space = 0) {
+  if ((path == NULL) || (path[0] == '\0')) {
+    err = ENOENT;
+    return NULL;
+  }
+
+  size_t path_len = strlen(path);
+  // Need to allocate at least room for 3 characters, since os::native_path transforms C: to C:.
+  char* buf = (char*) os::malloc(1 + MAX2((size_t) 3, path_len), mtInternal);
+  wchar_t* result = NULL;
+
+  if (buf == NULL) {
+    err = ENOMEM;
+  } else {
+    memcpy(buf, path, path_len + 1);
+    os::native_path(buf);
+
+    wchar_t* prefix;
+    int prefix_off = 0;
+    bool is_abs = true;
+    bool needs_fullpath = true;
+
+    if (::isalpha(buf[0]) && !::IsDBCSLeadByte(buf[0]) && buf[1] == ':' && buf[2] == '\\') {
+      prefix = L"\\\\?\\";
+    } else if (buf[0] == '\\' && buf[1] == '\\') {
+      assert(buf[2] != '\\');
+
+      if (buf[2] == '?' && buf[3] == '\\') {
+        prefix = L"";
+        needs_fullpath = false;
       } else {
-        err = ENOMEM;
+        prefix = L"\\\\?\\UNC";
+        prefix_off = 1; // Overwrite the first char with the prefix, so \\share\path becomes \\?\UNC\share\path
       }
     } else {
-      // only UNC pathname includes double slashes here
-      wpath = (wchar_t*)os::malloc((path_len + 7) * sizeof(wchar_t), mtInternal);
-      if (wpath != NULL) {
-        ::wcscpy(wpath, L"\\\\?\\UNC\0");
-        err = ::mbstowcs_s(&converted_chars, &wpath[7], path_len, path, path_len);
-      } else {
-        err = ENOMEM;
+      is_abs = false;
+      prefix = L"\\\\?\\";
+    }
+
+    size_t buf_len = strlen(buf);
+    size_t prefix_len = wcslen(prefix);
+    size_t full_path_size = is_abs ? 1 + buf_len : JVM_MAXPATHLEN;
+    size_t result_size = prefix_len + full_path_size - prefix_off;
+    result = (wchar_t*) os::malloc(sizeof(wchar_t) * (additional_space + result_size), mtInternal);
+
+    if (result == NULL) {
+      err = ENOMEM;
+    } else {
+      size_t converted_chars;
+      wchar_t* path_start = result + prefix_len - prefix_off;
+      err = ::mbstowcs_s(&converted_chars, path_start, buf_len + 1, buf, buf_len);
+
+      if ((err == ERROR_SUCCESS) && needs_fullpath) {
+        wchar_t* tmp = (wchar_t*) os::malloc(sizeof(wchar_t) * full_path_size, mtInternal);
+
+        if (tmp == NULL) {
+          err = ENOMEM;
+        } else {
+          if (!_wfullpath(tmp, path_start, full_path_size)) {
+            err = ENOENT;
+          } else {
+            ::memcpy(path_start, tmp, (1 + wcslen(tmp)) * sizeof(wchar_t));
+          }
+
+          os::free(tmp);
+        }
+      }
+
+      memcpy(result, prefix, sizeof(wchar_t) * prefix_len);
+
+      // Remove trailing pathsep (not for \\?\<DRIVE>:\, since it would make it relative)
+      size_t result_len = wcslen(result);
+
+      if (result[result_len - 1] == L'\\') {
+        if (!(::iswalpha(result[4]) && result[5] == L':' && result_len == 7)) {
+          result[result_len - 1] = L'\0';
+        }
       }
     }
-  } else {
-    wpath = (wchar_t*)os::malloc((path_len + 4) * sizeof(wchar_t), mtInternal);
-    if (wpath != NULL) {
-      ::wcscpy(wpath, L"\\\\?\\\0");
-      err = ::mbstowcs_s(&converted_chars, &wpath[4], path_len, path, path_len);
-    } else {
-      err = ENOMEM;
-    }
-  }
-  return wpath;
-}
-
-static void destroy_unc_path(wchar_t* wpath) {
-  os::free(wpath);
+  }
+
+  os::free(buf);
+
+  if (err != ERROR_SUCCESS) {
+    os::free(result);
+    result = NULL;
+  }
+
+  return result;
 }
 
 int os::stat(const char *path, struct stat *sbuf) {
-  char* pathbuf = (char*)os::strdup(path, mtInternal);
-  if (pathbuf == NULL) {
-    errno = ENOMEM;
+  errno_t err;
+  wchar_t* wide_path = wide_abs_unc_path(path, err);
+
+  if (wide_path == NULL) {
+    errno = err;
     return -1;
   }
-  os::native_path(pathbuf);
-  int ret;
-  WIN32_FILE_ATTRIBUTE_DATA file_data;
-  // Not using stat() to avoid the problem described in JDK-6539723
-  if (strlen(path) < MAX_PATH) {
-    BOOL bret = ::GetFileAttributesExA(pathbuf, GetFileExInfoStandard, &file_data);
-    if (!bret) {
-      errno = ::GetLastError();
-      ret = -1;
-    }
-    else {
-      file_attribute_data_to_stat(sbuf, file_data);
-      ret = 0;
-    }
-  } else {
-    errno_t err = ERROR_SUCCESS;
-    wchar_t* wpath = create_unc_path(pathbuf, err);
-    if (err != ERROR_SUCCESS) {
-      if (wpath != NULL) {
-        destroy_unc_path(wpath);
-      }
-      os::free(pathbuf);
-      errno = err;
-      return -1;
-    }
-    BOOL bret = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &file_data);
-    if (!bret) {
-      errno = ::GetLastError();
-      ret = -1;
-    } else {
-      file_attribute_data_to_stat(sbuf, file_data);
-      ret = 0;
-    }
-    destroy_unc_path(wpath);
-  }
-  os::free(pathbuf);
-  return ret;
+
+  WIN32_FILE_ATTRIBUTE_DATA file_data;;
+  BOOL bret = ::GetFileAttributesExW(wide_path, GetFileExInfoStandard, &file_data);
+  os::free(wide_path);
+
+  if (!bret) {
+    errno = ::GetLastError();
+    return -1;
+  }
+
+  file_attribute_data_to_stat(sbuf, file_data);
+  return 0;
 }
 
 static HANDLE create_read_only_file_handle(const char* file) {
-  if (file == NULL) {
-    return INVALID_HANDLE_VALUE;
-  }
-
-  char* nativepath = (char*)os::strdup(file, mtInternal);
-  if (nativepath == NULL) {
-    errno = ENOMEM;
+  errno_t err;
+  wchar_t* wide_path = wide_abs_unc_path(file, err);
+
+  if (wide_path == NULL) {
+    errno = err;
     return INVALID_HANDLE_VALUE;
   }
-  os::native_path(nativepath);
-
-  size_t len = strlen(nativepath);
-  HANDLE handle = INVALID_HANDLE_VALUE;
-
-  if (len < MAX_PATH) {
-    handle = ::CreateFile(nativepath, 0, FILE_SHARE_READ,
-                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-  } else {
-    errno_t err = ERROR_SUCCESS;
-    wchar_t* wfile = create_unc_path(nativepath, err);
-    if (err != ERROR_SUCCESS) {
-      if (wfile != NULL) {
-        destroy_unc_path(wfile);
-      }
-      os::free(nativepath);
-      return INVALID_HANDLE_VALUE;
-    }
-    handle = ::CreateFileW(wfile, 0, FILE_SHARE_READ,
-                           NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-    destroy_unc_path(wfile);
-  }
-
-  os::free(nativepath);
+
+  HANDLE handle = ::CreateFileW(wide_path, 0, FILE_SHARE_READ,
+                                NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+  os::free(wide_path);
+
   return handle;
 }
 
@@ -4329,7 +4338,6 @@
   return result;
 }
 
-
 #define FT2INT64(ft) \
   ((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))
 
@@ -4434,38 +4442,22 @@
   return DontYieldALot;
 }
 
-// This method is a slightly reworked copy of JDK's sysOpen
-// from src/windows/hpi/src/sys_api_md.c
-
 int os::open(const char *path, int oflag, int mode) {
-  char* pathbuf = (char*)os::strdup(path, mtInternal);
-  if (pathbuf == NULL) {
-    errno = ENOMEM;
+  errno_t err;
+  wchar_t* wide_path = wide_abs_unc_path(path, err);
+
+  if (wide_path == NULL) {
+    errno = err;
     return -1;
   }
-  os::native_path(pathbuf);
-  int ret;
-  if (strlen(path) < MAX_PATH) {
-    ret = ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode);
-  } else {
-    errno_t err = ERROR_SUCCESS;
-    wchar_t* wpath = create_unc_path(pathbuf, err);
-    if (err != ERROR_SUCCESS) {
-      if (wpath != NULL) {
-        destroy_unc_path(wpath);
-      }
-      os::free(pathbuf);
-      errno = err;
-      return -1;
-    }
-    ret = ::_wopen(wpath, oflag | O_BINARY | O_NOINHERIT, mode);
-    if (ret == -1) {
-      errno = ::GetLastError();
-    }
-    destroy_unc_path(wpath);
-  }
-  os::free(pathbuf);
-  return ret;
+  int fd = ::_wopen(wide_path, oflag | O_BINARY | O_NOINHERIT, mode);
+  os::free(wide_path);
+
+  if (fd == -1) {
+    errno = ::GetLastError();
+  }
+
+  return fd;
 }
 
 FILE* os::open(int fd, const char* mode) {
@@ -4474,37 +4466,26 @@
 
 // Is a (classpath) directory empty?
 bool os::dir_is_empty(const char* path) {
-  char* search_path = (char*)os::malloc(strlen(path) + 3, mtInternal);
-  if (search_path == NULL) {
-    errno = ENOMEM;
-    return false;
-  }
-  strcpy(search_path, path);
-  os::native_path(search_path);
-  // Append "*", or possibly "\\*", to path
-  if (search_path[1] == ':' &&
-       (search_path[2] == '\0' ||
-         (search_path[2] == '\\' && search_path[3] == '\0'))) {
-    // No '\\' needed for cases like "Z:" or "Z:\"
-    strcat(search_path, "*");
-  }
-  else {
-    strcat(search_path, "\\*");
-  }
-  errno_t err = ERROR_SUCCESS;
-  wchar_t* wpath = create_unc_path(search_path, err);
-  if (err != ERROR_SUCCESS) {
-    if (wpath != NULL) {
-      destroy_unc_path(wpath);
-    }
-    os::free(search_path);
+  errno_t err;
+  wchar_t* wide_path = wide_abs_unc_path(path, err, 2);
+
+  if (wide_path == NULL) {
     errno = err;
     return false;
   }
+
+  // Make sure we end with "\\*"
+  if (wide_path[wcslen(wide_path) - 1] == L'\\') {
+    wcscat(wide_path, L"*");
+  } else {
+    wcscat(wide_path, L"\\*");
+  }
+
   WIN32_FIND_DATAW fd;
-  HANDLE f = ::FindFirstFileW(wpath, &fd);
-  destroy_unc_path(wpath);
+  HANDLE f = ::FindFirstFileW(wide_path, &fd);
+  os::free(wide_path);
   bool is_empty = true;
+
   if (f != INVALID_HANDLE_VALUE) {
     while (is_empty && ::FindNextFileW(f, &fd)) {
       // An empty directory contains only the current directory file
@@ -4515,8 +4496,10 @@
       }
     }
     FindClose(f);
-  }
-  os::free(search_path);
+  } else {
+    errno = ::GetLastError();
+  }
+
   return is_empty;
 }
 
--- a/src/hotspot/share/adlc/formssel.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/adlc/formssel.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -4047,6 +4047,7 @@
         strcmp(opType,"FmaD") == 0 ||
         strcmp(opType,"FmaF") == 0 ||
         strcmp(opType,"RoundDouble")==0 ||
+        strcmp(opType,"RoundDoubleMode")==0 ||
         strcmp(opType,"RoundFloat")==0 ||
         strcmp(opType,"ReverseBytesI")==0 ||
         strcmp(opType,"ReverseBytesL")==0 ||
@@ -4175,7 +4176,7 @@
     "URShiftVB","URShiftVS","URShiftVI","URShiftVL",
     "MaxReductionV", "MinReductionV",
     "ReplicateB","ReplicateS","ReplicateI","ReplicateL","ReplicateF","ReplicateD",
-    "LoadVector","StoreVector",
+    "RoundDoubleModeV","LoadVector","StoreVector",
     "FmaVD", "FmaVF","PopCountVI",
     // Next are not supported currently.
     "PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D",
--- a/src/hotspot/share/classfile/vmSymbols.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/classfile/vmSymbols.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -575,6 +575,9 @@
   case vmIntrinsics::_intBitsToFloat:
   case vmIntrinsics::_doubleToRawLongBits:
   case vmIntrinsics::_longBitsToDouble:
+  case vmIntrinsics::_ceil:
+  case vmIntrinsics::_floor:
+  case vmIntrinsics::_rint:
   case vmIntrinsics::_dabs:
   case vmIntrinsics::_fabs:
   case vmIntrinsics::_iabs:
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Tue Oct 01 23:54:39 2019 -0400
@@ -766,6 +766,7 @@
   do_name(tan_name,"tan")       do_name(atan2_name,"atan2")     do_name(sqrt_name,"sqrt")                               \
   do_name(log_name,"log")       do_name(log10_name,"log10")     do_name(pow_name,"pow")                                 \
   do_name(exp_name,"exp")       do_name(min_name,"min")         do_name(max_name,"max")                                 \
+  do_name(floor_name, "floor")  do_name(ceil_name, "ceil")      do_name(rint_name, "rint")                              \
                                                                                                                         \
   do_name(addExact_name,"addExact")                                                                                     \
   do_name(decrementExact_name,"decrementExact")                                                                         \
@@ -781,6 +782,9 @@
   do_intrinsic(_iabs,                     java_lang_Math,         abs_name,   int_int_signature,           F_S)   \
   do_intrinsic(_labs,                     java_lang_Math,         abs_name,   long_long_signature,           F_S)   \
   do_intrinsic(_dsin,                     java_lang_Math,         sin_name,   double_double_signature,           F_S)   \
+  do_intrinsic(_floor,                    java_lang_Math,         floor_name, double_double_signature,           F_S)   \
+  do_intrinsic(_ceil,                     java_lang_Math,         ceil_name,  double_double_signature,           F_S)   \
+  do_intrinsic(_rint,                     java_lang_Math,         rint_name,  double_double_signature,           F_S)   \
   do_intrinsic(_dcos,                     java_lang_Math,         cos_name,   double_double_signature,           F_S)   \
   do_intrinsic(_dtan,                     java_lang_Math,         tan_name,   double_double_signature,           F_S)   \
   do_intrinsic(_datan2,                   java_lang_Math,         atan2_name, double2_double_signature,          F_S)   \
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -327,14 +327,25 @@
   ShenandoahHeapRegion* next_from_region(ShenandoahHeapRegionSet* slice) {
     ShenandoahHeapRegion* from_region = _heap_regions.next();
 
-    while (from_region != NULL && (!from_region->is_move_allowed() || from_region->is_humongous())) {
+    // Look for next candidate for this slice:
+    while (from_region != NULL) {
+      // Empty region: get it into the slice to defragment the slice itself.
+      // We could have skipped this without violating correctness, but we really
+      // want to compact all live regions to the start of the heap, which sometimes
+      // means moving them into the fully empty regions.
+      if (from_region->is_empty()) break;
+
+      // Can move the region, and this is not the humongous region. Humongous
+      // moves are special cased here, because their moves are handled separately.
+      if (from_region->is_move_allowed() && !from_region->is_humongous()) break;
+
       from_region = _heap_regions.next();
     }
 
     if (from_region != NULL) {
       assert(slice != NULL, "sanity");
       assert(!from_region->is_humongous(), "this path cannot handle humongous regions");
-      assert(from_region->is_move_allowed(), "only regions that can be moved in mark-compact");
+      assert(from_region->is_empty() || from_region->is_move_allowed(), "only regions that can be moved in mark-compact");
       slice->add_region(from_region);
     }
 
--- a/src/hotspot/share/opto/c2compiler.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/opto/c2compiler.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -462,6 +462,11 @@
   case vmIntrinsics::_writebackPostSync0:
     if (!Matcher::match_rule_supported(Op_CacheWBPostSync)) return false;
     break;
+  case vmIntrinsics::_rint:
+  case vmIntrinsics::_ceil:
+  case vmIntrinsics::_floor:
+    if (!Matcher::match_rule_supported(Op_RoundDoubleMode)) return false;
+    break;
   case vmIntrinsics::_hashCode:
   case vmIntrinsics::_identityHashCode:
   case vmIntrinsics::_getClass:
--- a/src/hotspot/share/opto/classes.hpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/opto/classes.hpp	Tue Oct 01 23:54:39 2019 -0400
@@ -274,6 +274,8 @@
 macro(Return)
 macro(Root)
 macro(RoundDouble)
+macro(RoundDoubleMode)
+macro(RoundDoubleModeV)
 macro(RoundFloat)
 macro(SafePoint)
 macro(SafePointScalarObject)
--- a/src/hotspot/share/opto/convertnode.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/opto/convertnode.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -531,4 +531,16 @@
   return phase->type( in(1) );
 }
 
-
+//=============================================================================
+//------------------------------Identity---------------------------------------
+// Remove redundant roundings.
+Node* RoundDoubleModeNode::Identity(PhaseGVN* phase) {
+  int op = in(1)->Opcode();
+  // Redundant rounding e.g. floor(ceil(n)) -> ceil(n)
+  if(op == Op_RoundDoubleMode) return in(1);
+  return this;
+}
+const Type* RoundDoubleModeNode::Value(PhaseGVN* phase) const {
+  return Type::DOUBLE;
+}
+//=============================================================================
--- a/src/hotspot/share/opto/convertnode.hpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/opto/convertnode.hpp	Tue Oct 01 23:54:39 2019 -0400
@@ -212,5 +212,16 @@
   virtual const Type* Value(PhaseGVN* phase) const;
 };
 
+//-----------------------------RoundDoubleModeNode-----------------------------
+class RoundDoubleModeNode: public Node {
+  public:
+  RoundDoubleModeNode(Node *in1, Node * rmode): Node(0, in1, rmode) {}
+  virtual int   Opcode() const;
+  virtual const Type *bottom_type() const { return Type::DOUBLE; }
+  virtual uint  ideal_reg() const { return Op_RegD; }
+  virtual Node* Identity(PhaseGVN* phase);
+  virtual const Type* Value(PhaseGVN* phase) const;
+};
+
 
 #endif // SHARE_OPTO_CONVERTNODE_HPP
--- a/src/hotspot/share/opto/library_call.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/opto/library_call.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -534,6 +534,9 @@
   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 
+  case vmIntrinsics::_ceil:
+  case vmIntrinsics::_floor:
+  case vmIntrinsics::_rint:
   case vmIntrinsics::_dsin:
   case vmIntrinsics::_dcos:
   case vmIntrinsics::_dtan:
@@ -1818,6 +1821,9 @@
   switch (id) {
   case vmIntrinsics::_dabs:   n = new AbsDNode(                arg);  break;
   case vmIntrinsics::_dsqrt:  n = new SqrtDNode(C, control(),  arg);  break;
+  case vmIntrinsics::_ceil:   n = new RoundDoubleModeNode(arg, makecon(TypeInt::make(2))); break;
+  case vmIntrinsics::_floor:  n = new RoundDoubleModeNode(arg, makecon(TypeInt::make(1))); break;
+  case vmIntrinsics::_rint:   n = new RoundDoubleModeNode(arg, makecon(TypeInt::make(0))); break;
   default:  fatal_unexpected_iid(id);  break;
   }
   set_result(_gvn.transform(n));
@@ -1891,6 +1897,9 @@
       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
 
     // These intrinsics are supported on all hardware
+  case vmIntrinsics::_ceil:
+  case vmIntrinsics::_floor:
+  case vmIntrinsics::_rint:   return Matcher::match_rule_supported(Op_RoundDoubleMode) ? inline_double_math(id) : false;
   case vmIntrinsics::_dsqrt:  return Matcher::match_rule_supported(Op_SqrtD) ? inline_double_math(id) : false;
   case vmIntrinsics::_dabs:   return Matcher::has_match_rule(Op_AbsD)   ? inline_double_math(id) : false;
   case vmIntrinsics::_fabs:   return Matcher::match_rule_supported(Op_AbsF)   ? inline_math(id) : false;
--- a/src/hotspot/share/opto/superword.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/opto/superword.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -2401,6 +2401,12 @@
         const TypePtr* atyp = n->adr_type();
         vn = StoreVectorNode::make(opc, ctl, mem, adr, atyp, val, vlen);
         vlen_in_bytes = vn->as_StoreVector()->memory_size();
+      } else if (VectorNode::is_roundopD(n)) {
+        Node* in1 = vector_opd(p, 1);
+        Node* in2 = low_adr->in(2);
+        assert(in2->is_Con(), "Constant rounding mode expected.");
+        vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n));
+        vlen_in_bytes = vn->as_Vector()->length_in_bytes();
       } else if (VectorNode::is_muladds2i(n)) {
         assert(n->req() == 5u, "MulAddS2I should have 4 operands.");
         Node* in1 = vector_opd(p, 1);
--- a/src/hotspot/share/opto/vectornode.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/opto/vectornode.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -128,6 +128,9 @@
   case Op_NegD:
     assert(bt == T_DOUBLE, "must be");
     return Op_NegVD;
+  case Op_RoundDoubleMode:
+    assert(bt == T_DOUBLE, "must be");
+    return Op_RoundDoubleModeV;
   case Op_SqrtF:
     assert(bt == T_FLOAT, "must be");
     return Op_SqrtVF;
@@ -259,6 +262,13 @@
   return false;
 }
 
+bool VectorNode::is_roundopD(Node *n) {
+  if (n->Opcode() == Op_RoundDoubleMode) {
+    return true;
+  }
+  return false;
+}
+
 bool VectorNode::is_shift(Node* n) {
   switch (n->Opcode()) {
   case Op_LShiftI:
@@ -407,6 +417,8 @@
   case Op_MinV: return new MinVNode(n1, n2, vt);
   case Op_MaxV: return new MaxVNode(n1, n2, vt);
 
+  case Op_RoundDoubleModeV: return new RoundDoubleModeVNode(n1, n2, vt);
+
   case Op_MulAddVS2VI: return new MulAddVS2VINode(n1, n2, vt);
   default:
     fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
--- a/src/hotspot/share/opto/vectornode.hpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/hotspot/share/opto/vectornode.hpp	Tue Oct 01 23:54:39 2019 -0400
@@ -70,6 +70,7 @@
   static bool is_type_transition_short_to_int(Node* n);
   static bool is_type_transition_to_int(Node* n);
   static bool is_muladds2i(Node* n);
+  static bool is_roundopD(Node * n);
   static bool is_invariant_vector(Node* n);
   // [Start, end) half-open range defining which operands are vectors
   static void vector_operands(Node* n, uint* start, uint* end);
@@ -447,6 +448,13 @@
   SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
   virtual int Opcode() const;
 };
+//------------------------------RoundDoubleVNode--------------------------------
+// Vector round double
+class RoundDoubleModeVNode : public VectorNode {
+ public:
+  RoundDoubleModeVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
+  virtual int Opcode() const;
+};
 
 //------------------------------SqrtVDNode--------------------------------------
 // Vector Sqrt double
--- a/src/java.base/share/classes/java/lang/Math.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/java.base/share/classes/java/lang/Math.java	Tue Oct 01 23:54:39 2019 -0400
@@ -440,6 +440,7 @@
      *          floating-point value that is greater than or equal to
      *          the argument and is equal to a mathematical integer.
      */
+    @HotSpotIntrinsicCandidate
     public static double ceil(double a) {
         return StrictMath.ceil(a); // default impl. delegates to StrictMath
     }
@@ -459,6 +460,7 @@
      *          floating-point value that less than or equal to the argument
      *          and is equal to a mathematical integer.
      */
+    @HotSpotIntrinsicCandidate
     public static double floor(double a) {
         return StrictMath.floor(a); // default impl. delegates to StrictMath
     }
@@ -478,6 +480,7 @@
      * @return  the closest floating-point value to {@code a} that is
      *          equal to a mathematical integer.
      */
+    @HotSpotIntrinsicCandidate
     public static double rint(double a) {
         return StrictMath.rint(a); // default impl. delegates to StrictMath
     }
--- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java	Tue Oct 01 23:54:39 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -707,11 +707,7 @@
                 }  else {
                     // try once more
                     openServer();
-                    if (needsTunneling()) {
-                        MessageHeader origRequests = requests;
-                        httpuc.doTunneling();
-                        requests = origRequests;
-                    }
+                    checkTunneling(httpuc);
                     afterConnect();
                     writeRequests(requests, poster);
                     return parseHTTP(responses, pi, httpuc);
@@ -722,6 +718,18 @@
 
     }
 
+    // Check whether tunnel must be open and open it if necessary
+    // (in the case of HTTPS with proxy)
+    private void checkTunneling(HttpURLConnection httpuc) throws IOException {
+        if (needsTunneling()) {
+            MessageHeader origRequests = requests;
+            PosterOutputStream origPoster = poster;
+            httpuc.doTunneling();
+            requests = origRequests;
+            poster = origPoster;
+        }
+    }
+
     private boolean parseHTTPHeader(MessageHeader responses, ProgressSource pi, HttpURLConnection httpuc)
     throws IOException {
         /* If "HTTP/*" is found in the beginning, return true.  Let
@@ -849,11 +857,7 @@
                         closeServer();
                         cachedHttpClient = false;
                         openServer();
-                        if (needsTunneling()) {
-                            MessageHeader origRequests = requests;
-                            httpuc.doTunneling();
-                            requests = origRequests;
-                        }
+                        checkTunneling(httpuc);
                         afterConnect();
                         writeRequests(requests, poster);
                         return parseHTTP(responses, pi, httpuc);
--- a/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c	Tue Oct 01 23:54:39 2019 -0400
@@ -511,7 +511,7 @@
     if (buffer == NULL) {
         RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");
     }
-    strncpy(buffer, allowed_peers, len);
+    memcpy(buffer, allowed_peers, len);
     buffer[len] = '\0';
 
     jdwpTransportError err = parseAllowedPeersInternal(buffer);
--- a/src/jdk.jshell/share/classes/jdk/jshell/ExpressionToTypeInfo.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/src/jdk.jshell/share/classes/jdk/jshell/ExpressionToTypeInfo.java	Tue Oct 01 23:54:39 2019 -0400
@@ -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
@@ -149,6 +149,7 @@
     private static class Result extends Error {
 
         static final long serialVersionUID = -5942088234594905629L;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         final TreePath expressionPath;
 
         Result(TreePath path) {
--- a/test/hotspot/gtest/runtime/test_os_windows.cpp	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/hotspot/gtest/runtime/test_os_windows.cpp	Tue Oct 01 23:54:39 2019 -0400
@@ -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
@@ -85,4 +85,595 @@
         << "Failed to allocate memory at requested location " << expected_location << " of size " << expected_allocation_size;
 }
 
+// The types of path modifications we randomly apply to a path. They should not change the file designated by the path.
+enum ModsFilter {
+  Allow_None = 0, // No modifications
+  Allow_Sep_Mods = 1, // Replace '\\' by any sequence of '/' or '\\' or at least length 1.
+  Allow_Dot_Path = 2, // Add /. segments at random positions
+  Allow_Dot_Dot_Path = 4, // Add /../<correct-dir> segments at random positions.
+  Allow_All = Allow_Sep_Mods | Allow_Dot_Path | Allow_Dot_Dot_Path
+};
+
+// The mode in which to run.
+enum Mode {
+  TEST, // Runs the test. This is the normal modus.
+  EXAMPLES, // Runs example which document the behaviour of the Windows system calls.
+  BENCH // Runs a small benchmark which tries to show the costs of using the *W variants/_wfullpath.
+};
+
+// Parameters of the test.
+static ModsFilter mods_filter = Allow_All;
+static int mods_per_path = 50; // The number of variants of a path we try.
+static Mode mode = TEST;
+
+
+// Utility methods
+static void get_current_dir_w(wchar_t* path, size_t size) {
+  DWORD count = GetCurrentDirectoryW((DWORD) size, path);
+  EXPECT_GT((int) count, 0) << "Failed to get current directory: " << GetLastError();
+  EXPECT_LT((size_t) count, size) << "Buffer too small for current directory: " << size;
+}
+
+#define WITH_ABS_PATH(path) \
+  wchar_t abs_path[JVM_MAXPATHLEN]; \
+  wchar_t cwd[JVM_MAXPATHLEN]; \
+  get_current_dir_w(cwd, JVM_MAXPATHLEN); \
+  wsprintfW(abs_path, L"\\\\?\\%ls\\%ls", cwd, (path))
+
+static bool file_exists_w(const wchar_t* path) {
+  WIN32_FILE_ATTRIBUTE_DATA file_data;
+  return ::GetFileAttributesExW(path, GetFileExInfoStandard, &file_data);
+}
+
+static void create_rel_directory_w(const wchar_t* path) {
+  WITH_ABS_PATH(path);
+  EXPECT_FALSE(file_exists_w(abs_path)) <<  "Can't create directory: \"" << path << "\" already exists";
+  BOOL result = CreateDirectoryW(abs_path, NULL);
+  EXPECT_TRUE(result) << "Failed to create directory \"" << path << "\" " << GetLastError();
+}
+
+static void delete_empty_rel_directory_w(const wchar_t* path) {
+  WITH_ABS_PATH(path);
+  EXPECT_TRUE(file_exists_w(abs_path)) << "Can't delete directory: \"" << path << "\" does not exists";
+  BOOL result = RemoveDirectoryW(abs_path);
+  EXPECT_TRUE(result) << "Failed to delete directory \"" << path << "\": " << GetLastError();
+}
+
+static void create_rel_file_w(const wchar_t* path) {
+  WITH_ABS_PATH(path);
+  EXPECT_FALSE(file_exists_w(abs_path)) << "Can't create file: \"" << path << "\" already exists";
+  HANDLE h = CreateFileW(abs_path, 0, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+  EXPECT_NE(h, INVALID_HANDLE_VALUE) << "Failed to create file \"" << path << "\": " << GetLastError();
+  CloseHandle(h);
+}
+
+static void delete_rel_file_w(const wchar_t* path) {
+  WITH_ABS_PATH(path);
+  EXPECT_TRUE(file_exists_w(abs_path)) << "Can't delete file: \"" << path << "\" does not exists";
+  BOOL result = DeleteFileW(abs_path);
+  EXPECT_TRUE(result) << "Failed to delete file \"" << path << "\": " << GetLastError();
+}
+
+static bool convert_to_cstring(char* c_str, size_t size, wchar_t* w_str) {
+  size_t converted;
+  errno_t err = wcstombs_s(&converted, c_str, size, w_str, size - 1);
+  EXPECT_EQ(err, ERROR_SUCCESS) << "Could not convert \"" << w_str << "\" to c-string";
+
+  return err == ERROR_SUCCESS;
+}
+
+static wchar_t* my_wcscpy_s(wchar_t* dest, size_t size, wchar_t* start, const wchar_t* to_copy) {
+  size_t already_used = dest - start;
+  size_t len = wcslen(to_copy);
+
+  if (already_used + len < size) {
+    wcscpy_s(dest, size - already_used, to_copy);
+  }
+
+  return dest + wcslen(to_copy);
+}
+
+// The currently finite list of seperator sequences we might use instead of '\\'.
+static const wchar_t* sep_replacements[] = {
+  L"\\", L"\\/", L"/", L"//", L"\\\\/\\", L"//\\/"
+};
+
+// Takes a path and modifies it in a way that it should still designate the same file.
+static bool unnormalize_path(wchar_t* result, size_t size, bool is_dir, const wchar_t* path) {
+  wchar_t* dest = result;
+  const wchar_t* src = path;
+  const wchar_t* path_start;
+
+  if (wcsncmp(src, L"\\\\?\\UNC\\", 8) == 0) {
+    path_start = src + 8;
+  } else if (wcsncmp(src, L"\\\\?\\", 4) == 0) {
+    if (src[5] == L':') {
+      path_start = src + 6;
+    } else {
+      path_start = wcschr(src + 4, L'\\');
+    }
+  } else if (wcsncmp(src, L"\\\\", 2) == 0) {
+    path_start = wcschr(src + 2, L'?');
+
+    if (path_start == NULL) {
+      path_start = wcschr(src + 2, L'\\');
+    } else {
+      path_start = wcschr(path_start, L'\\');
+    }
+  } else {
+    path_start = wcschr(src + 1, L'\\');
+  }
+
+  bool allow_sep_change = (mods_filter & Allow_Sep_Mods) && (os::random() & 1) == 0;
+  bool allow_dot_change = (mods_filter & Allow_Dot_Path) && (os::random() & 1) == 0;
+  bool allow_dotdot_change = (mods_filter & Allow_Dot_Dot_Path) && (os::random() & 1) == 0;
+
+  while ((*src != L'\0') && (result + size > dest)) {
+    wchar_t c = *src;
+    *dest = c;
+    ++src;
+    ++dest;
+
+    if (c == L'\\') {
+      if (allow_sep_change && (os::random() & 3) == 3) {
+        int i = os::random() % (sizeof(sep_replacements) / sizeof(sep_replacements[0]));
+
+        if (i >= 0) {
+          const wchar_t* replacement = sep_replacements[i];
+          dest = my_wcscpy_s(dest - 1, size,  result, replacement);
+        }
+      } else if (path_start != NULL) {
+        if (allow_dotdot_change && (src > path_start + 1) && ((os::random() & 7) == 7)) {
+          wchar_t const* last_sep = src - 2;
+
+          while (last_sep[0] != L'\\') {
+            --last_sep;
+          }
+
+          if (last_sep > path_start) {
+            dest = my_wcscpy_s(dest, size, result, L"../");
+            src = last_sep + 1;
+          }
+        } else if (allow_dot_change && (src > path_start + 1) && ((os::random() & 7) == 7)) {
+          dest = my_wcscpy_s(dest, size, result, L"./");
+        }
+      }
+    }
+  }
+
+  while (is_dir && ((os::random() & 15) == 1)) {
+    dest = my_wcscpy_s(dest, size, result, L"/");
+  }
+
+  if (result + size > dest) {
+    *dest = L'\0';
+  }
+
+  // Use this modification only if not too close to the max size.
+  return result + size - 10 > dest;
+}
+
+static void check_dir_impl(wchar_t* path, bool should_be_empty) {
+  char buf[JVM_MAXPATHLEN];
+
+  if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
+    struct stat st;
+    EXPECT_EQ(os::stat(buf, &st), 0) << "os::stat failed for \"" << path << "\"";
+    EXPECT_EQ(st.st_mode & S_IFMT, S_IFDIR) << "\"" << path << "\" is not a directory according to os::stat";
+    errno = ERROR_SUCCESS;
+    bool is_empty = os::dir_is_empty(buf);
+    errno_t err = errno;
+    EXPECT_EQ(is_empty, should_be_empty) << "os::dir_is_empty assumed \"" << path << "\" is "
+                                         << (should_be_empty ?  "not ": "") << "empty";
+    EXPECT_EQ(err, ERROR_SUCCESS) << "os::dir_is_empty failed for \"" << path << "\"with errno " << err;
+  }
+}
+
+static void check_file_impl(wchar_t* path) {
+  char buf[JVM_MAXPATHLEN];
+
+  if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
+    struct stat st;
+    EXPECT_EQ(os::stat(buf, &st), 0) << "os::stat failed for \"" << path << "\"";
+    EXPECT_EQ(st.st_mode & S_IFMT, S_IFREG) << "\"" << path << "\" is not a regular file according to os::stat";
+    int fd = os::open(buf, O_RDONLY, 0);
+    EXPECT_NE(fd, -1) << "os::open failed for \"" << path << "\" with errno " << errno;
+    if (fd >= 0) {
+      ::close(fd);
+    }
+  }
+}
+
+static void check_file_not_present_impl(wchar_t* path) {
+  char buf[JVM_MAXPATHLEN];
+
+  if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
+    struct stat st;
+    int stat_ret;
+    EXPECT_EQ(stat_ret = os::stat(buf, &st), -1) << "os::stat did not fail for \"" << path << "\"";
+    if (stat_ret != -1) {
+      // Only check open if stat not already failed.
+      int fd = os::open(buf, O_RDONLY, 0);
+      EXPECT_EQ(fd, -1) << "os::open did not fail for \"" << path << "\"";
+      if (fd >= 0) {
+        ::close(fd);
+      }
+    }
+  }
+}
+
+static void check_dir(wchar_t* path, bool should_be_empty) {
+  check_dir_impl(path, should_be_empty);
+
+  for (int i = 0; mods_filter != Allow_None && i < mods_per_path; ++i) {
+    wchar_t tmp[JVM_MAXPATHLEN];
+    if (unnormalize_path(tmp, JVM_MAXPATHLEN, true, path)) {
+      check_dir_impl(tmp, should_be_empty);
+    }
+  }
+}
+
+static void check_file(wchar_t* path) {
+  check_file_impl(path);
+
+  // Check os::same_files at least somewhat.
+  char buf[JVM_MAXPATHLEN];
+
+  if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
+    wchar_t mod[JVM_MAXPATHLEN];
+
+    if (unnormalize_path(mod, JVM_MAXPATHLEN, false, path)) {
+      char mod_c[JVM_MAXPATHLEN];
+      if (convert_to_cstring(mod_c, JVM_MAXPATHLEN, mod)) {
+        EXPECT_EQ(os::same_files(buf, mod_c), true) << "os::same files failed for \\" << path << "\" and \"" << mod_c << "\"";
+      }
+    }
+  }
+
+  for (int i = 0; mods_filter != Allow_None && i < mods_per_path; ++i) {
+    wchar_t tmp[JVM_MAXPATHLEN];
+    if (unnormalize_path(tmp, JVM_MAXPATHLEN, false, path)) {
+      check_file_impl(tmp);
+    }
+  }
+}
+
+static void check_file_not_present(wchar_t* path) {
+  check_file_not_present_impl(path);
+
+  for (int i = 0; mods_filter != Allow_None && i < mods_per_path; ++i) {
+    wchar_t tmp[JVM_MAXPATHLEN];
+    if (unnormalize_path(tmp, JVM_MAXPATHLEN, false, path)) {
+      check_file_not_present_impl(tmp);
+    }
+  }
+}
+
+static void record_path(char const* name, char const* len_name, wchar_t* path) {
+  char buf[JVM_MAXPATHLEN];
+
+  if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
+    ::testing::Test::RecordProperty(name, buf);
+    snprintf(buf, JVM_MAXPATHLEN, "%d", (int) wcslen(path));
+    ::testing::Test::RecordProperty(len_name, buf);
+  }
+}
+
+static void bench_path(wchar_t* path) {
+  char buf[JVM_MAXPATHLEN];
+  int reps = 100000;
+
+  if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
+    jlong wtime[2];
+
+    for (int t = 0; t < 2; ++t) {
+      wtime[t] = os::javaTimeNanos();
+
+      for (int i = 0; i < reps; ++i) {
+        bool succ = false;
+        size_t buf_len = strlen(buf);
+        wchar_t* w_path = (wchar_t*) os::malloc(sizeof(wchar_t) * (buf_len + 1), mtInternal);
+
+        if (w_path != NULL) {
+          size_t converted_chars;
+          if (::mbstowcs_s(&converted_chars, w_path, buf_len + 1, buf, buf_len) == ERROR_SUCCESS) {
+            if (t == 1) {
+              wchar_t* tmp = (wchar_t*) os::malloc(sizeof(wchar_t) * JVM_MAXPATHLEN, mtInternal);
+
+              if (tmp) {
+                if (_wfullpath(tmp, w_path, JVM_MAXPATHLEN)) {
+                  succ = true;
+                }
+
+                // Note that we really don't use the full path name, but just add the cost of running _wfullpath.
+                os::free(tmp);
+              }
+              if (!succ) {
+                printf("Failed fullpathing \"%s\"\n", buf);
+                return;
+              }
+              succ = false;
+            }
+            HANDLE h = ::CreateFileW(w_path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+            if (h != INVALID_HANDLE_VALUE) {
+              ::CloseHandle(h);
+              succ = true;
+            }
+          }
+        }
+
+        os::free(w_path);
+        if (!succ) {
+          printf("Failed getting W*attr. \"%s\"\n", buf);
+          return;
+        }
+      }
+
+      wtime[t] = os::javaTimeNanos() - wtime[t];
+    }
+
+    jlong ctime = os::javaTimeNanos();
+
+    for (int i = 0; i < reps; ++i) {
+      HANDLE h = ::CreateFileA(buf, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+      if (h == INVALID_HANDLE_VALUE) {
+        return;
+      }
+
+      ::CloseHandle(h);
+    }
+
+    ctime = os::javaTimeNanos() - ctime;
+
+    printf("\"%s\" %f us for *A, %f us for *W, %f us for *W with fullpath\n", buf,
+      0.001 * ctime / reps, 0.001 * wtime[0] / reps, 0.001 * wtime[1] / reps);
+  }
+}
+
+static void print_attr_result_for_path(wchar_t* path) {
+  WIN32_FILE_ATTRIBUTE_DATA file_data;
+  struct stat st;
+  char buf[JVM_MAXPATHLEN];
+  wchar_t abs[JVM_MAXPATHLEN];
+
+  _wfullpath(abs, path, JVM_MAXPATHLEN);
+  printf("Checking \"%ls\" (%d chars):\n", path, (int) wcslen(path));
+  printf("_wfullpath             %ls (%d chars)\n", abs, (int) wcslen(abs));
+  BOOL bret = ::GetFileAttributesExW(path, GetFileExInfoStandard, &file_data);
+  printf("GetFileAttributesExW() %s\n", bret ? "success" : "failed");
+
+  if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
+    bret = ::GetFileAttributesExA(buf, GetFileExInfoStandard, &file_data);
+    printf("GetFileAttributesExA() %s\n", bret ? "success" : "failed");
+
+    bool succ = os::stat(buf, &st) != -1;
+    printf("os::stat()             %s\n", succ ? "success" : "failed");
+  }
+}
+
+static void print_attr_result(wchar_t* format, ...) {
+  va_list argptr;
+  wchar_t buf[JVM_MAXPATHLEN];
+
+  va_start(argptr, format);
+  wvsprintfW(buf, format, argptr);
+  print_attr_result_for_path(buf);
+  va_end(argptr);
+}
+
+#define RECORD_PATH(name) record_path(#name, #name "Len", name)
+#define NAME_PART_50 L"01234567890123456789012345678901234567890123456789"
+#define NAME_PART_250 NAME_PART_50 NAME_PART_50 NAME_PART_50 NAME_PART_50 NAME_PART_50
+
+// Test which tries to find out if the os::stat, os::open, os::same_files and os::dir_is_empty methods
+// can handle long path names correctly.
+TEST_VM(os_windows, handle_long_paths) {
+  static wchar_t cwd[JVM_MAXPATHLEN];
+  static wchar_t nearly_long_rel_path[JVM_MAXPATHLEN];
+  static wchar_t long_rel_path[JVM_MAXPATHLEN];
+  static wchar_t empty_dir_rel_path[JVM_MAXPATHLEN];
+  static wchar_t not_empty_dir_rel_path[JVM_MAXPATHLEN];
+  static wchar_t file_rel_path[JVM_MAXPATHLEN];
+  static wchar_t nearly_long_file_rel_path[JVM_MAXPATHLEN];
+  static wchar_t nearly_long_path[JVM_MAXPATHLEN];
+  static wchar_t empty_dir_path[JVM_MAXPATHLEN];
+  static wchar_t not_empty_dir_path[JVM_MAXPATHLEN];
+  static wchar_t nearly_long_file_path[JVM_MAXPATHLEN];
+  static wchar_t file_path[JVM_MAXPATHLEN];
+  static wchar_t nearly_long_unc_path[JVM_MAXPATHLEN];
+  static wchar_t empty_dir_unc_path[JVM_MAXPATHLEN];
+  static wchar_t not_empty_dir_unc_path[JVM_MAXPATHLEN];
+  static wchar_t nearly_long_file_unc_path[JVM_MAXPATHLEN];
+  static wchar_t file_unc_path[JVM_MAXPATHLEN];
+  static wchar_t root_dir_path[JVM_MAXPATHLEN];
+  static wchar_t root_rel_dir_path[JVM_MAXPATHLEN];
+
+  wchar_t* dir_prefix = L"os_windows_long_paths_dir_";
+  wchar_t* empty_dir_name = L"empty_directory_with_long_path";
+  wchar_t* not_empty_dir_name = L"not_empty_directory_with_long_path";
+  wchar_t* file_name = L"file";
+  wchar_t dir_letter;
+  WIN32_FILE_ATTRIBUTE_DATA file_data;
+  bool can_test_unc = false;
+
+  get_current_dir_w(cwd, sizeof(cwd) / sizeof(wchar_t));
+  dir_letter = (cwd[1] == L':' ? cwd[0] : L'\0');
+  int cwd_len = (int) wcslen(cwd);
+  int dir_prefix_len = (int) wcslen(dir_prefix);
+  int rel_path_len = MAX2(dir_prefix_len, 235 - cwd_len);
+
+  memcpy(nearly_long_rel_path, dir_prefix, sizeof(wchar_t) * dir_prefix_len);
+
+  for (int i = dir_prefix_len; i < rel_path_len; ++i) {
+    nearly_long_rel_path[i] = L'L';
+  }
+
+  nearly_long_rel_path[rel_path_len] = L'\0';
+
+  wsprintfW(long_rel_path, L"%ls\\%ls", nearly_long_rel_path, NAME_PART_250);
+  wsprintfW(empty_dir_rel_path, L"%ls\\%ls", nearly_long_rel_path, empty_dir_name);
+  wsprintfW(not_empty_dir_rel_path, L"%ls\\%ls", nearly_long_rel_path, not_empty_dir_name);
+  wsprintfW(nearly_long_file_rel_path, L"%ls\\%ls", nearly_long_rel_path, file_name);
+  wsprintfW(file_rel_path, L"%ls\\%ls\\%ls", nearly_long_rel_path, not_empty_dir_name, file_name);
+  wsprintfW(nearly_long_path, L"\\\\?\\%ls\\%ls", cwd, nearly_long_rel_path);
+  wsprintfW(empty_dir_path, L"%ls\\%ls", nearly_long_path, empty_dir_name);
+  wsprintfW(not_empty_dir_path, L"%ls\\%ls", nearly_long_path, not_empty_dir_name);
+  wsprintfW(nearly_long_file_path, L"%ls\\%ls", nearly_long_path, file_name);
+  wsprintfW(file_path, L"%ls\\%ls\\%ls", nearly_long_path, not_empty_dir_name, file_name);
+  wsprintfW(nearly_long_unc_path, L"\\\\localhost\\%lc$\\%s", dir_letter, nearly_long_path + 7);
+  wsprintfW(empty_dir_unc_path, L"%s\\%s", nearly_long_unc_path, empty_dir_name);
+  wsprintfW(not_empty_dir_unc_path, L"%s\\%s", nearly_long_unc_path, not_empty_dir_name);
+  wsprintfW(nearly_long_file_unc_path, L"%ls\\%ls", nearly_long_unc_path, file_name);
+  wsprintfW(file_unc_path, L"%s\\%s\\%s", nearly_long_unc_path, not_empty_dir_name, file_name);
+  wsprintfW(root_dir_path, L"%lc:\\", dir_letter);
+  wsprintfW(root_rel_dir_path, L"%lc:", dir_letter);
+
+  RECORD_PATH(long_rel_path);
+  RECORD_PATH(nearly_long_rel_path);
+  RECORD_PATH(nearly_long_path);
+  RECORD_PATH(nearly_long_unc_path);
+  RECORD_PATH(empty_dir_rel_path);
+  RECORD_PATH(empty_dir_path);
+  RECORD_PATH(empty_dir_unc_path);
+  RECORD_PATH(not_empty_dir_rel_path);
+  RECORD_PATH(not_empty_dir_path);
+  RECORD_PATH(not_empty_dir_unc_path);
+  RECORD_PATH(nearly_long_file_rel_path);
+  RECORD_PATH(nearly_long_file_path);
+  RECORD_PATH(nearly_long_file_unc_path);
+  RECORD_PATH(file_rel_path);
+  RECORD_PATH(file_path);
+  RECORD_PATH(file_unc_path);
+
+  create_rel_directory_w(nearly_long_rel_path);
+  create_rel_directory_w(long_rel_path);
+  create_rel_directory_w(empty_dir_rel_path);
+  create_rel_directory_w(not_empty_dir_rel_path);
+  create_rel_file_w(nearly_long_file_rel_path);
+  create_rel_file_w(file_rel_path);
+
+  // For UNC path test we assume that the current DRIVE has a share
+  // called "<DRIVELETTER>$" (so for D: we expect \\localhost\D$ to be
+  // the same). Since this is only an assumption, we have to skip
+  // the UNC tests if the share is missing.
+  if (dir_letter && !::GetFileAttributesExW(nearly_long_unc_path, GetFileExInfoStandard, &file_data)) {
+    printf("Disabled UNC path test, since %lc: is not mapped as share %lc$.\n", dir_letter, dir_letter);
+  } else {
+    can_test_unc = true;
+  }
+
+  if (mode == BENCH) {
+    bench_path(nearly_long_path + 4);
+    bench_path(nearly_long_rel_path);
+    bench_path(nearly_long_file_path + 4);
+    bench_path(nearly_long_file_rel_path);
+  } else if (mode == EXAMPLES) {
+    printf("Working directory: %ls", cwd);
+
+    if (dir_letter) {
+      static wchar_t top_buf[JVM_MAXPATHLEN];
+      wchar_t* top_path = wcschr(cwd + 3, L'\\');
+
+      if (top_path) {
+        size_t top_len = (top_path - cwd) - 3;
+
+        memcpy(top_buf, cwd + 3, top_len * 2);
+        top_buf[top_len] = L'\0';
+        top_path = top_buf;
+      }
+
+      print_attr_result(L"%lc:\\", dir_letter);
+      print_attr_result(L"%lc:\\.\\", dir_letter);
+
+      if (top_path) {
+        print_attr_result(L"%lc:\\%ls\\..\\%ls\\", dir_letter, top_path, top_path);
+      }
+
+      print_attr_result(L"%lc:", dir_letter);
+      print_attr_result(L"%lc:.", dir_letter);
+      print_attr_result(L"%lc:\\COM1", dir_letter);
+      print_attr_result(L"%lc:\\PRN", dir_letter);
+      print_attr_result(L"%lc:\\PRN\\COM1", dir_letter);
+      print_attr_result(L"\\\\?\\UNC\\localhost\\%lc$\\", dir_letter);
+      print_attr_result(L"\\\\?\\UNC\\\\localhost\\%lc$\\", dir_letter);
+      print_attr_result(nearly_long_unc_path);
+      print_attr_result(L"%ls\\.\\", nearly_long_unc_path);
+      print_attr_result(L"%ls\\..\\%ls", nearly_long_unc_path, nearly_long_rel_path);
+      print_attr_result(L"\\\\?\\UNC\\%ls", nearly_long_unc_path + 2);
+      print_attr_result(file_unc_path);
+      print_attr_result(L"%ls\\%ls\\..\\%ls\\%ls", nearly_long_unc_path, not_empty_dir_name, not_empty_dir_name, file_name);
+      print_attr_result(L"%ls\\%ls\\.\\%ls", nearly_long_unc_path, not_empty_dir_name, file_name);
+      print_attr_result(L"\\\\?\\UNC\\%ls", file_unc_path + 2);
+      print_attr_result(L"\\\\?\\UNC\\%ls\\%ls\\.\\%ls", nearly_long_unc_path + 2, not_empty_dir_name, file_name);
+      print_attr_result(L"\\\\?\\UNC\\%ls\\%ls\\..\\%ls\\%ls", nearly_long_unc_path + 2, not_empty_dir_name, not_empty_dir_name, file_name);
+    }
+
+    print_attr_result(nearly_long_rel_path);
+    print_attr_result(L"%ls\\.\\", nearly_long_rel_path);
+    print_attr_result(L"%ls\\..\\%ls", nearly_long_rel_path, nearly_long_rel_path);
+    print_attr_result(L"%\\\\?\\%ls", nearly_long_rel_path);
+    print_attr_result(L"\\\\?\\%ls\\.\\", nearly_long_rel_path);
+    print_attr_result(L"\\\\?\\%ls\\..\\%ls", nearly_long_rel_path, nearly_long_rel_path);
+
+    print_attr_result(nearly_long_path + 4);
+    print_attr_result(L"%ls\\.\\", nearly_long_path + 4);
+    print_attr_result(L"%ls\\..\\%ls", nearly_long_path + 4, nearly_long_rel_path);
+    print_attr_result(nearly_long_path);
+    print_attr_result(L"%ls\\.\\", nearly_long_path);
+    print_attr_result(L"%ls\\..\\%ls", nearly_long_path, nearly_long_rel_path);
+  } else {
+    check_file_not_present(L"");
+
+    // Check relative paths
+    check_dir(nearly_long_rel_path, false);
+    check_dir(long_rel_path, true);
+    check_dir(empty_dir_rel_path, true);
+    check_dir(not_empty_dir_rel_path, false);
+    check_file(nearly_long_file_rel_path);
+    check_file(file_rel_path);
+
+    // Check absolute paths
+    if (dir_letter) {
+      check_dir(root_dir_path, false);
+      check_dir(root_rel_dir_path, false);
+    }
+
+    check_dir(cwd, false);
+    check_dir(nearly_long_path + 4, false);
+    check_dir(empty_dir_path + 4, true);
+    check_dir(not_empty_dir_path + 4, false);
+    check_file(nearly_long_file_path + 4);
+    check_file(file_path + 4);
+
+    // Check UNC paths
+    if (can_test_unc) {
+      check_dir(nearly_long_unc_path, false);
+      check_dir(empty_dir_unc_path, true);
+      check_dir(not_empty_dir_unc_path, false);
+      check_file(nearly_long_file_unc_path);
+      check_file(file_unc_path);
+    }
+
+    // Check handling of <DRIVE>:/../<OTHER_DRIVE>:/path/...
+    // The other drive letter should not overwrite the original one.
+    if (dir_letter) {
+      static wchar_t tmp[JVM_MAXPATHLEN];
+      wchar_t* other_letter = dir_letter == L'D' ? L"C" : L"D";
+      wsprintfW(tmp, L"%2ls\\..\\%ls:%ls", nearly_long_file_path, other_letter, nearly_long_file_path + 2);
+      check_file_not_present(tmp);
+      wsprintfW(tmp, L"%2ls\\..\\%ls:%ls", file_path, other_letter, file_path + 2);
+      check_file_not_present(tmp);
+    }
+  }
+
+  delete_rel_file_w(file_rel_path);
+  delete_rel_file_w(nearly_long_file_rel_path);
+  delete_empty_rel_directory_w(not_empty_dir_rel_path);
+  delete_empty_rel_directory_w(empty_dir_rel_path);
+  delete_empty_rel_directory_w(long_rel_path);
+  delete_empty_rel_directory_w(nearly_long_rel_path);
+}
+
 #endif
--- a/test/hotspot/jtreg/compiler/c2/cr6340864/TestDoubleVect.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/hotspot/jtreg/compiler/c2/cr6340864/TestDoubleVect.java	Tue Oct 01 23:54:39 2019 -0400
@@ -87,6 +87,9 @@
       test_divv(a0, a1, -VALUE);
       test_diva(a0, a1, a3);
       test_negc(a0, a1);
+      test_rint(a0, a1);
+      test_ceil(a0, a1);
+      test_floor(a0, a1);
     }
     // Test and verify results
     System.out.println("Verification");
@@ -351,6 +354,56 @@
         errn += verify("test_negc: ", i, a0[i], (double)(-((double)(ADD_INIT+i))));
       }
 
+      // To test -ve and +ve Zero scenarios.
+      double [] other_corner_cases     = { -0.0, 0.0, 9.007199254740992E15 };
+      double [] other_corner_cases_res = new double[3];
+      test_floor(a0, a1);
+      errn += verify("test_floor: ", 0, a0[0], Double.NaN);
+      errn += verify("test_floor: ", 1, a0[1], Double.POSITIVE_INFINITY);
+      errn += verify("test_floor: ", 2, a0[2], Double.NEGATIVE_INFINITY);
+      errn += verify("test_floor: ", 3, a0[3], Double.MAX_VALUE);
+      errn += verify("test_floor: ", 4, a0[4], 0.0);
+      errn += verify("test_floor: ", 5, a0[5], 0.0);
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_floor: ", i, a0[i], ((double)(ADD_INIT+i)));
+      }
+      test_floor_cc(other_corner_cases_res, other_corner_cases);
+      errn += verify("test_floor_cc: ", 0, other_corner_cases_res[0], -0.0);
+      errn += verify("test_floor_cc: ", 1, other_corner_cases_res[1], 0.0);
+      errn += verify("test_floor_cc: ", 2, other_corner_cases_res[2], 9.007199254740992E15);
+
+      test_ceil(a0, a1);
+      errn += verify("test_ceil: ", 0, a0[0], Double.NaN);
+      errn += verify("test_ceil: ", 1, a0[1], Double.POSITIVE_INFINITY);
+      errn += verify("test_ceil: ", 2, a0[2], Double.NEGATIVE_INFINITY);
+      errn += verify("test_ceil: ", 3, a0[3], Double.MAX_VALUE);
+      errn += verify("test_ceil: ", 4, a0[4], 1.0);
+      errn += verify("test_ceil: ", 5, a0[5], 1.0);
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_ceil: ", i, a0[i], ((double)(ADD_INIT+i+1.0)));
+      }
+      test_ceil_cc(other_corner_cases_res, other_corner_cases);
+      errn += verify("test_ceil_cc: ", 0, other_corner_cases_res[0], -0.0);
+      errn += verify("test_ceil_cc: ", 1, other_corner_cases_res[1], 0.0);
+      errn += verify("test_ceil_cc: ", 2, other_corner_cases_res[2], 9.007199254740992E15);
+
+      test_rint(a0, a1);
+      errn += verify("test_rint: ", 0, a0[0], Double.NaN);
+      errn += verify("test_rint: ", 1, a0[1], Double.POSITIVE_INFINITY);
+      errn += verify("test_rint: ", 2, a0[2], Double.NEGATIVE_INFINITY);
+      errn += verify("test_rint: ", 3, a0[3], Double.MAX_VALUE);
+      errn += verify("test_rint: ", 4, a0[4], 0.0);
+      errn += verify("test_rint: ", 5, a0[5], 0.0);
+      for (int i=6; i<ARRLEN; i++) {
+        if ( i <= 500 )
+           errn += verify("test_rint: ", i, a0[i], ((double)(ADD_INIT+i)));
+        else
+           errn += verify("test_rint: ", i, a0[i], ((double)(ADD_INIT+i+1.0)));
+      }
+      test_rint_cc(other_corner_cases_res, other_corner_cases);
+      errn += verify("test_rint_cc: ", 0, other_corner_cases_res[0], -0.0);
+      errn += verify("test_rint_cc: ", 1, other_corner_cases_res[1], 0.0);
+      errn += verify("test_rint_cc: ", 2, other_corner_cases_res[2], 9.007199254740992E15);
     }
 
     if (errn > 0)
@@ -577,6 +630,37 @@
     }
   }
 
+  static void test_rint(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = Math.rint(a1[i] + ((double)(i))/1000);
+    }
+  }
+  static void test_ceil(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = Math.ceil(a1[i] + ((double)(i))/1000);
+    }
+  }
+  static void test_floor(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = Math.floor(a1[i] + ((double)(i))/1000);
+    }
+  }
+  static void test_rint_cc(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = Math.rint(a1[i]);
+    }
+  }
+  static void test_ceil_cc(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = Math.ceil(a1[i]);
+    }
+  }
+  static void test_floor_cc(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = Math.floor(a1[i]);
+    }
+  }
+
   static int verify(String text, int i, double elem, double val) {
     if (elem != val && !(Double.isNaN(elem) && Double.isNaN(val))) {
       System.err.println(text + "[" + i + "] = " + elem + " != " + val);
--- a/test/hotspot/jtreg/compiler/escapeAnalysis/TestSelfArrayCopy.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/hotspot/jtreg/compiler/escapeAnalysis/TestSelfArrayCopy.java	Tue Oct 01 23:54:39 2019 -0400
@@ -26,7 +26,7 @@
  * @bug 8229016 8231055
  * @summary Test correct elimination of array allocation with arraycopy to itself.
  * @library /test/lib
- * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.escapeAnalysis.TestSelfArrayCopy::test
+ * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.escapeAnalysis.TestSelfArrayCopy::test*
  *                   compiler.escapeAnalysis.TestSelfArrayCopy
  */
 
--- a/test/hotspot/jtreg/runtime/LoadClass/LongBCP.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/hotspot/jtreg/runtime/LoadClass/LongBCP.java	Tue Oct 01 23:54:39 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -39,7 +39,6 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
-import jdk.test.lib.Platform;
 import jdk.test.lib.compiler.CompilerUtils;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
@@ -126,13 +125,8 @@
             bootCP, "Hello");
 
         output = new OutputAnalyzer(pb.start());
-        if (!Platform.isWindows()) {
-            output.shouldContain("Hello World")
-                  .shouldHaveExitValue(0);
-        } else {
-            output.shouldContain("Could not find or load main class Hello")
-                  .shouldHaveExitValue(1);
-        }
+        output.shouldContain("Hello World")
+              .shouldHaveExitValue(0);
 
         // total relative path length exceeds MAX_PATH
         destDir = Paths.get(destDir.toString(), "yyyyyyyy");
@@ -144,12 +138,7 @@
             bootCP, "Hello");
 
         output = new OutputAnalyzer(pb.start());
-        if (!Platform.isWindows()) {
-            output.shouldContain("Hello World")
-                  .shouldHaveExitValue(0);
-        } else {
-            output.shouldContain("Could not find or load main class Hello")
-                  .shouldHaveExitValue(1);
-        }
+        output.shouldContain("Hello World")
+              .shouldHaveExitValue(0);
     }
 }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Allocate/alloc001/TestDescription.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Allocate/alloc001/TestDescription.java	Tue Oct 01 23:54:39 2019 -0400
@@ -42,6 +42,8 @@
  * @library /vmTestbase
  *          /test/lib
  * @requires os.family != "aix"
+ * @comment Test is incompatible with ZGC, due to ZGC's address space requirements.
+ * @requires vm.gc != "Z"
  * @run driver jdk.test.lib.FileInstaller . .
  * @build nsk.jvmti.Allocate.alloc001
  * @run shell alloc001.sh
--- a/test/jdk/ProblemList.txt	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/jdk/ProblemList.txt	Tue Oct 01 23:54:39 2019 -0400
@@ -250,7 +250,7 @@
 java/awt/font/TextLayout/TextLayoutBounds.java 8169188 generic-all
 java/awt/font/StyledMetrics/BoldSpace.java 8198422 linux-all
 java/awt/FontMetrics/FontCrash.java 8198336 windows-all
-java/awt/FontMetrics/MaxAdvanceIsMax.java 8221305 solaris-all,macosx-all
+java/awt/FontMetrics/MaxAdvanceIsMax.java 8221305,8231495 solaris-all,macosx-all,linux-all
 java/awt/image/DrawImage/IncorrectAlphaSurface2SW.java 8056077 generic-all
 java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java 8196025 windows-all
 java/awt/image/DrawImage/IncorrectClipXorModeSurface2Surface.java 8196025 windows-all
--- a/test/jdk/java/io/File/SetLastModified.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/jdk/java/io/File/SetLastModified.java	Tue Oct 01 23:54:39 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -23,6 +23,7 @@
 
 /* @test
    @bug 4091757 6652379 8177809
+   @requires os.maxMemory >= 16G
    @summary Basic test for setLastModified method
  */
 
--- a/test/jdk/java/net/MulticastSocket/UnreferencedMulticastSockets.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/jdk/java/net/MulticastSocket/UnreferencedMulticastSockets.java	Tue Oct 01 23:54:39 2019 -0400
@@ -50,6 +50,7 @@
 import java.util.ArrayDeque;
 import java.util.List;
 import java.util.Optional;
+import java.util.concurrent.Phaser;
 import java.util.concurrent.TimeUnit;
 
 import jdk.test.lib.net.IPSupport;
@@ -72,11 +73,14 @@
     static class Server implements Runnable {
 
         MulticastSocket ss;
-
+        final int port;
+        final Phaser phaser = new Phaser(2);
         Server() throws IOException {
+            InetAddress loopback = InetAddress.getLoopbackAddress();
             InetSocketAddress serverAddress =
-                new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
+                new InetSocketAddress(loopback, 0);
             ss = new MulticastSocket(serverAddress);
+            port = ss.getLocalPort();
             System.out.printf("  DatagramServer addr: %s: %d%n",
                     this.getHost(), this.getPort());
             pendingSockets.add(new NamedWeak(ss, pendingQueue, "serverMulticastSocket"));
@@ -89,7 +93,7 @@
         }
 
         int getPort() {
-            return ss.getLocalPort();
+            return port;
         }
 
         // Receive a byte and send back a byte
@@ -98,12 +102,18 @@
                 byte[] buffer = new byte[50];
                 DatagramPacket p = new DatagramPacket(buffer, buffer.length);
                 ss.receive(p);
+                System.out.printf("Server: ping received from: %s%n", p.getSocketAddress());
+                phaser.arriveAndAwaitAdvance(); // await the client...
                 buffer[0] += 1;
+                System.out.printf("Server: sending echo to: %s%n", p.getSocketAddress());
                 ss.send(p);         // send back +1
 
+                System.out.printf("Server: awaiting client%n");
+                phaser.arriveAndAwaitAdvance(); // await the client...
                 // do NOT close but 'forget' the socket reference
+                System.out.printf("Server: forgetting socket...%n");
                 ss = null;
-            } catch (Exception ioe) {
+            } catch (Throwable ioe) {
                 ioe.printStackTrace();
             }
         }
@@ -112,8 +122,11 @@
     public static void main(String args[]) throws Exception {
         IPSupport.throwSkippedExceptionIfNonOperational();
 
+        InetSocketAddress clientAddress =
+                new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
+
         // Create and close a MulticastSocket to warm up the FD count for side effects.
-        try (MulticastSocket s = new MulticastSocket(0)) {
+        try (MulticastSocket s = new MulticastSocket(clientAddress)) {
             // no-op; close immediately
             s.getLocalPort();   // no-op
         }
@@ -126,8 +139,33 @@
         Thread thr = new Thread(svr);
         thr.start();
 
-        MulticastSocket client = new MulticastSocket(0);
-        System.out.printf("  client bound port: %d%n", client.getLocalPort());
+        // It is possible under some circumstances that the client
+        // might get bound to the same port than the server: this
+        // would make the test fail - so if this happen we try to
+        // bind to a specific port by incrementing the server port.
+        MulticastSocket client = null;
+        int serverPort = svr.getPort();
+        int maxtries = 20;
+        for (int i = 0; i < maxtries; i++) {
+            try {
+                System.out.printf("Trying to bind client to: %s%n", clientAddress);
+                client = new MulticastSocket(clientAddress);
+                if (client.getLocalPort() != svr.getPort()) break;
+                client.close();
+            } catch (IOException x) {
+                System.out.printf("Couldn't create client after %d attempts: %s%n", i, x);
+                if (i == maxtries) throw x;
+            }
+            if (i == maxtries) {
+                String msg = String.format("Couldn't create client after %d attempts", i);
+                System.out.println(msg);
+                throw new AssertionError(msg);
+            }
+            clientAddress = new InetSocketAddress(clientAddress.getAddress(), serverPort + i);
+        }
+
+        System.out.printf("  client bound port: %s:%d%n",
+                client.getLocalAddress(), client.getLocalPort());
         client.connect(svr.getHost(), svr.getPort());
         pendingSockets.add(new NamedWeak(client, pendingQueue, "clientMulticastSocket"));
         extractRefs(client, "clientMulticastSocket");
@@ -136,14 +174,17 @@
         msg[0] = 1;
         DatagramPacket p = new DatagramPacket(msg, msg.length, svr.getHost(), svr.getPort());
         client.send(p);
+        System.out.printf("  ping sent to: %s:%d%n", svr.getHost(), svr.getPort());
+        svr.phaser.arriveAndAwaitAdvance(); // wait until the server has received its packet
 
         p = new DatagramPacket(msg, msg.length);
         client.receive(p);
 
-        System.out.printf("echo received from: %s%n", p.getSocketAddress());
+        System.out.printf("  echo received from: %s%n", p.getSocketAddress());
         if (msg[0] != 2) {
             throw new AssertionError("incorrect data received: expected: 2, actual: " + msg[0]);
         }
+        svr.phaser.arriveAndAwaitAdvance(); // let the server null out its socket
 
         // Do NOT close the MulticastSocket; forget it
 
--- a/test/jdk/java/net/SocketImpl/SocketImplCombinations.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/jdk/java/net/SocketImpl/SocketImplCombinations.java	Tue Oct 01 23:54:39 2019 -0400
@@ -68,7 +68,7 @@
      * Test creating a connected Socket, it should be created with a platform SocketImpl.
      */
     public void testNewSocket2() throws IOException {
-        try (ServerSocket ss = new ServerSocket(0)) {
+        try (ServerSocket ss = boundServerSocket()) {
             try (Socket s = new Socket(ss.getInetAddress(), ss.getLocalPort())) {
                 SocketImpl si = getSocketImpl(s);
                 assertTrue(isSocksSocketImpl(si));
@@ -127,7 +127,7 @@
         Socket s = new Socket((SocketImpl) null) { };
         try (s) {
             assertTrue(getSocketImpl(s) == null);
-            s.bind(new InetSocketAddress(0));   // force SocketImpl to be created
+            s.bind(loopbackSocketAddress());   // force SocketImpl to be created
             SocketImpl si = getSocketImpl(s);
             assertTrue(isSocksSocketImpl(si));
             SocketImpl delegate = getDelegate(si);
@@ -218,7 +218,7 @@
             Socket s = new Socket((SocketImpl) null) { };
             try (s) {
                 assertTrue(getSocketImpl(s) == null);
-                s.bind(new InetSocketAddress(0));   // force SocketImpl to be created
+                s.bind(loopbackSocketAddress());   // force SocketImpl to be created
                 assertTrue(getSocketImpl(s) instanceof CustomSocketImpl);
             }
         } finally {
@@ -378,7 +378,7 @@
     public void testServerSocketAccept5a() throws IOException {
         SocketImpl serverImpl = new CustomSocketImpl(true);
         try (ServerSocket ss = new ServerSocket(serverImpl) { }) {
-            ss.bind(new InetSocketAddress(0));
+            ss.bind(loopbackSocketAddress());
             expectThrows(IOException.class, ss::accept);
         }
     }
@@ -566,16 +566,36 @@
     }
 
     /**
+     * Returns a new InetSocketAddress with the loopback interface
+     * and port 0.
+     */
+    static InetSocketAddress loopbackSocketAddress() {
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        return new InetSocketAddress(loopback, 0);
+    }
+
+    /**
+     * Returns a ServerSocket bound to a port on the loopback address
+     */
+    static ServerSocket boundServerSocket() throws IOException {
+        ServerSocket ss = new ServerSocket();
+        ss.bind(loopbackSocketAddress());
+        return ss;
+    }
+
+    /**
      * Creates a ServerSocket that returns the given Socket from accept.
      */
     static ServerSocket serverSocketToAccept(Socket s) throws IOException {
-        return new ServerSocket(0) {
+        ServerSocket ss = new ServerSocket() {
             @Override
             public Socket accept() throws IOException {
                 implAccept(s);
                 return s;
             }
         };
+        ss.bind(loopbackSocketAddress());
+        return ss;
     }
 
     /**
@@ -590,7 +610,7 @@
                 return s;
             }
         };
-        ss.bind(new InetSocketAddress(0));
+        ss.bind(loopbackSocketAddress());
         return ss;
     }
 
--- a/test/jdk/java/net/httpclient/DigestEchoServer.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/jdk/java/net/httpclient/DigestEchoServer.java	Tue Oct 01 23:54:39 2019 -0400
@@ -26,6 +26,8 @@
 import com.sun.net.httpserver.HttpsConfigurator;
 import com.sun.net.httpserver.HttpsParameters;
 import com.sun.net.httpserver.HttpsServer;
+
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -1568,8 +1570,8 @@
                 @Override
                 public void run() {
                     try {
+                        int c = 0;
                         try {
-                            int c;
                             while ((c = is.read()) != -1) {
                                 os.write(c);
                                 os.flush();
@@ -1578,11 +1580,13 @@
                                 if (DEBUG) System.out.print(tag);
                             }
                             is.close();
+                        } catch (IOException ex) {
+                            if (DEBUG || !stopped && c >  -1)
+                                ex.printStackTrace(System.out);
+                            end.completeExceptionally(ex);
                         } finally {
-                            os.close();
+                            try {os.close();} catch (Throwable t) {}
                         }
-                    } catch (IOException ex) {
-                        if (DEBUG) ex.printStackTrace(System.out);
                     } finally {
                         end.complete(null);
                     }
@@ -1632,10 +1636,12 @@
         @Override
         public void run() {
             Socket clientConnection = null;
+            Socket targetConnection = null;
             try {
                 while (!stopped) {
                     System.out.println(now() + "Tunnel: Waiting for client");
                     Socket toClose;
+                    targetConnection = clientConnection = null;
                     try {
                         toClose = clientConnection = ss.accept();
                         if (NO_LINGER) {
@@ -1649,7 +1655,6 @@
                     }
                     System.out.println(now() + "Tunnel: Client accepted");
                     StringBuilder headers = new StringBuilder();
-                    Socket targetConnection = null;
                     InputStream  ccis = clientConnection.getInputStream();
                     OutputStream ccos = clientConnection.getOutputStream();
                     Writer w = new OutputStreamWriter(
@@ -1769,28 +1774,44 @@
                             end1 = new CompletableFuture<>());
                     Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-',
                             end2 = new CompletableFuture<>());
-                    end = CompletableFuture.allOf(end1, end2);
+                    var end11 = end1.whenComplete((r, t) -> exceptionally(end2, t));
+                    var end22 = end2.whenComplete((r, t) ->  exceptionally(end1, t));
+                    end = CompletableFuture.allOf(end11, end22);
+                    Socket tc = targetConnection;
                     end.whenComplete(
                             (r,t) -> {
                                 try { toClose.close(); } catch (IOException x) { }
+                                try { tc.close(); } catch (IOException x) { }
                                 finally {connectionCFs.remove(end);}
                             });
                     connectionCFs.add(end);
+                    targetConnection = clientConnection = null;
                     t1.start();
                     t2.start();
                 }
             } catch (Throwable ex) {
-                try {
-                    ss.close();
-                } catch (IOException ex1) {
-                    ex.addSuppressed(ex1);
-                }
+                close(clientConnection, ex);
+                close(targetConnection, ex);
+                close(ss, ex);
                 ex.printStackTrace(System.err);
             } finally {
                 System.out.println(now() + "Tunnel: exiting (stopped=" + stopped + ")");
                 connectionCFs.forEach(cf -> cf.complete(null));
             }
         }
+
+        void exceptionally(CompletableFuture<?> cf, Throwable t) {
+            if (t != null) cf.completeExceptionally(t);
+        }
+
+        void close(Closeable c, Throwable e) {
+            if (c == null) return;
+            try {
+                c.close();
+            } catch (IOException x) {
+                e.addSuppressed(x);
+            }
+        }
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/net/www/http/HttpClient/B8209178.java	Tue Oct 01 23:54:39 2019 -0400
@@ -0,0 +1,409 @@
+/*
+ * 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 8209178
+ * @modules java.base/sun.net.www java.base/sun.security.x509 java.base/sun.security.tools.keytool
+ * @library /test/lib
+ * @run main/othervm -Dsun.net.http.retryPost=true B8209178
+ * @run main/othervm -Dsun.net.http.retryPost=false B8209178
+ * @summary Proxied HttpsURLConnection doesn't send BODY when retrying POST request
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import javax.net.ssl.*;
+
+import com.sun.net.httpserver.*;
+import jdk.test.lib.net.URIBuilder;
+import sun.security.tools.keytool.CertAndKeyGen;
+import sun.security.x509.X500Name;
+
+public class B8209178 {
+    static {
+        try {
+            HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
+            SSLContext.setDefault(new TestSSLContext().get());
+        } catch (Exception ex) {
+            throw new ExceptionInInitializerError(ex);
+        }
+    }
+
+    static final String RESPONSE = "<html><body><p>Hello World!</body></html>";
+    static final String PATH = "/foo/";
+    static final String RETRYPOST = System.getProperty("sun.net.http.retryPost");
+
+    static HttpServer createHttpsServer() throws IOException, NoSuchAlgorithmException {
+        HttpsServer server = HttpsServer.create();
+        HttpContext context = server.createContext(PATH);
+        context.setHandler(new HttpHandler() {
+
+            boolean simulateError = true;
+
+            @Override
+            public void handle(HttpExchange he) throws IOException {
+
+                System.out.printf("%s - received request on : %s%n",
+                        Thread.currentThread().getName(),
+                        he.getRequestURI());
+                System.out.printf("%s - received request headers : %s%n",
+                        Thread.currentThread().getName(),
+                        new HashMap(he.getRequestHeaders()));
+
+                InputStream requestBody = he.getRequestBody();
+                String body = B8209178.toString(requestBody);
+
+                System.out.printf("%s - received request body : %s%n",
+                        Thread.currentThread().getName(), body);
+
+                if (simulateError) {
+                    simulateError = false;
+
+                    System.out.printf("%s - closing connection unexpectedly ... %n",
+                            Thread.currentThread().getName(), he.getRequestHeaders());
+
+                    he.close(); // try not to respond anything the first time ...
+                    return;
+                }
+
+                he.getResponseHeaders().add("encoding", "UTF-8");
+                he.sendResponseHeaders(200, RESPONSE.length());
+                he.getResponseBody().write(RESPONSE.getBytes(StandardCharsets.UTF_8));
+                he.close();
+            }
+        });
+
+        server.setHttpsConfigurator(new Configurator(SSLContext.getDefault()));
+        server.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0);
+        return server;
+    }
+
+    public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
+        HttpServer server = createHttpsServer();
+        server.start();
+        try {
+            new B8209178().test(server);
+
+        } finally {
+            server.stop(0);
+            System.out.println("Server stopped");
+        }
+    }
+
+    public void test(HttpServer server /*, HttpClient.Version version*/) throws IOException {
+        System.out.println("System property retryPost: " + RETRYPOST);
+        System.out.println("Server is: " + server.getAddress());
+        System.out.println("Verifying communication with server");
+        URI uri = URIBuilder.newBuilder()
+                .scheme("https")
+                .host(server.getAddress().getAddress())
+                .port(server.getAddress().getPort())
+                .path(PATH + "x")
+                .buildUnchecked();
+
+        TunnelingProxy proxy = new TunnelingProxy(server);
+        proxy.start();
+
+        try {
+            System.out.println("Proxy started");
+            Proxy p = new Proxy(Proxy.Type.HTTP,
+                    InetSocketAddress.createUnresolved("localhost", proxy.getAddress().getPort()));
+            System.out.println("Verifying communication with proxy");
+
+            callHttpsServerThroughProxy(uri, p);
+
+        } finally {
+            System.out.println("Stopping proxy");
+            proxy.stop();
+            System.out.println("Proxy stopped");
+        }
+    }
+
+    private void callHttpsServerThroughProxy(URI uri, Proxy p) throws IOException {
+        HttpsURLConnection urlConnection = (HttpsURLConnection) uri.toURL().openConnection(p);
+
+        urlConnection.setConnectTimeout(1000);
+        urlConnection.setReadTimeout(3000);
+        urlConnection.setDoInput(true);
+        urlConnection.setDoOutput(true);
+        urlConnection.setRequestMethod("POST");
+        urlConnection.setUseCaches(false);
+
+        urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+        urlConnection.setRequestProperty("charset", "utf-8");
+        urlConnection.setRequestProperty("Connection", "keep-alive");
+
+        String urlParameters = "param1=a&param2=b&param3=c";
+        byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);
+
+        OutputStream outputStream = urlConnection.getOutputStream();
+        outputStream.write(postData);
+        outputStream.close();
+
+        int responseCode;
+
+        try {
+            responseCode = urlConnection.getResponseCode();
+            System.out.printf(" ResponseCode : %s%n", responseCode);
+            String output;
+            InputStream inputStream = (responseCode < 400) ? urlConnection.getInputStream() : urlConnection.getErrorStream();
+            output = toString(inputStream);
+            inputStream.close();
+            System.out.printf(" Output from server : %s%n", output);
+
+            if (responseCode == 200) {    // OK !
+            } else {
+                throw new RuntimeException("Bad response Code : " + responseCode);
+            }
+        } catch (SocketException se) {
+            if (RETRYPOST.equals("true")) {    // Should not get here with the fix
+                throw new RuntimeException("Unexpected Socket Exception: " + se);
+            } else {
+                System.out.println("Socket Exception received as expected: " + se);
+            }
+        }
+    }
+
+    static class TunnelingProxy {
+        final Thread accept;
+        final ServerSocket ss;
+        final boolean DEBUG = false;
+        final HttpServer serverImpl;
+
+        TunnelingProxy(HttpServer serverImpl) throws IOException {
+            this.serverImpl = serverImpl;
+            ss = new ServerSocket();
+            accept = new Thread(this::accept);
+        }
+
+        void start() throws IOException {
+            ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+            accept.start();
+        }
+
+        // Pipe the input stream to the output stream
+        private synchronized Thread pipe(InputStream is, OutputStream os, char tag) {
+            return new Thread("TunnelPipe(" + tag + ")") {
+                @Override
+                public void run() {
+                    try {
+                        try {
+                            int c;
+                            while ((c = is.read()) != -1) {
+                                os.write(c);
+                                os.flush();
+                                // if DEBUG prints a + or a - for each transferred
+                                // character.
+                                if (DEBUG) System.out.print(tag);
+                            }
+                            is.close();
+                        } finally {
+                            os.close();
+                        }
+                    } catch (IOException ex) {
+                        if (DEBUG) ex.printStackTrace(System.out);
+                    }
+                }
+            };
+        }
+
+        public InetSocketAddress getAddress() {
+            return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort());
+        }
+
+        // This is a bit shaky. It doesn't handle continuation
+        // lines, but our client shouldn't send any.
+        // Read a line from the input stream, swallowing the final
+        // \r\n sequence. Stops at the first \n, doesn't complain
+        // if it wasn't preceded by '\r'.
+        //
+        String readLine(InputStream r) throws IOException {
+            StringBuilder b = new StringBuilder();
+            int c;
+            while ((c = r.read()) != -1) {
+                if (c == '\n') {
+                    break;
+                }
+                b.appendCodePoint(c);
+            }
+            if (b.codePointAt(b.length() - 1) == '\r') {
+                b.delete(b.length() - 1, b.length());
+            }
+            return b.toString();
+        }
+
+        public void accept() {
+            Socket clientConnection = null;
+            try {
+                while (true) {
+                    System.out.println("Tunnel: Waiting for client");
+                    Socket previous = clientConnection;
+                    try {
+                        clientConnection = ss.accept();
+                    } catch (IOException io) {
+                        if (DEBUG) io.printStackTrace(System.out);
+                        break;
+                    } finally {
+                        // we have only 1 client at a time, so it is safe
+                        // to close the previous connection here
+                        if (previous != null) previous.close();
+                    }
+                    System.out.println("Tunnel: Client accepted");
+                    Socket targetConnection = null;
+                    InputStream ccis = clientConnection.getInputStream();
+                    OutputStream ccos = clientConnection.getOutputStream();
+                    Writer w = new OutputStreamWriter(ccos, "UTF-8");
+                    PrintWriter pw = new PrintWriter(w);
+                    System.out.println("Tunnel: Reading request line");
+                    String requestLine = readLine(ccis);
+                    System.out.println("Tunnel: Request status line: " + requestLine);
+                    if (requestLine.startsWith("CONNECT ")) {
+                        // We should probably check that the next word following
+                        // CONNECT is the host:port of our HTTPS serverImpl.
+                        // Some improvement for a followup!
+
+                        // Read all headers until we find the empty line that
+                        // signals the end of all headers.
+                        while (!requestLine.equals("")) {
+                            System.out.println("Tunnel: Reading header: "
+                                    + (requestLine = readLine(ccis)));
+                        }
+
+                        // Open target connection
+                        targetConnection = new Socket(
+                                serverImpl.getAddress().getAddress(),
+                                serverImpl.getAddress().getPort());
+
+                        // Then send the 200 OK response to the client
+                        System.out.println("Tunnel: Sending "
+                                + "HTTP/1.1 200 OK\r\n\r\n");
+                        pw.print("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+                        pw.flush();
+                    } else {
+                        // This should not happen
+                        throw new IOException("Tunnel: Unexpected status line: "
+                                + requestLine);
+                    }
+
+                    // Pipe the input stream of the client connection to the
+                    // output stream of the target connection and conversely.
+                    // Now the client and target will just talk to each other.
+                    System.out.println("Tunnel: Starting tunnel pipes");
+                    Thread t1 = pipe(ccis, targetConnection.getOutputStream(), '+');
+                    Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-');
+                    t1.start();
+                    t2.start();
+
+                    // We have only 1 client... wait until it has finished before
+                    // accepting a new connection request.
+                    System.out.println("Tunnel: Waiting for pipes to close");
+                    t1.join();
+                    t2.join();
+                    System.out.println("Tunnel: Done - waiting for next client");
+                }
+            } catch (Throwable ex) {
+                try {
+                    ss.close();
+                } catch (IOException ex1) {
+                    ex.addSuppressed(ex1);
+                }
+                ex.printStackTrace(System.err);
+            }
+        }
+
+        void stop() throws IOException {
+            ss.close();
+        }
+    }
+
+    static class Configurator extends HttpsConfigurator {
+        public Configurator(SSLContext ctx) {
+            super(ctx);
+        }
+
+        @Override
+        public void configure(HttpsParameters params) {
+            params.setSSLParameters(getSSLContext().getSupportedSSLParameters());
+        }
+    }
+
+
+    static class TestSSLContext {
+
+        SSLContext ssl;
+
+        public TestSSLContext() throws Exception {
+            init();
+        }
+
+        private void init() throws Exception {
+
+            CertAndKeyGen keyGen = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
+            keyGen.generate(1024);
+
+            //Generate self signed certificate
+            X509Certificate[] chain = new X509Certificate[1];
+            chain[0] = keyGen.getSelfCertificate(new X500Name("CN=ROOT"), (long) 365 * 24 * 3600);
+
+            char[] passphrase = "passphrase".toCharArray();
+
+            KeyStore ks = KeyStore.getInstance("JKS");
+            ks.load(null, passphrase); // must be "initialized" ...
+
+            ks.setKeyEntry("server", keyGen.getPrivateKey(), passphrase, chain);
+
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+            kmf.init(ks, passphrase);
+
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+            tmf.init(ks);
+
+            ssl = SSLContext.getInstance("TLS");
+            ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+        }
+
+        public SSLContext get() {
+            return ssl;
+        }
+    }
+
+    // ###############################################################################################
+
+    private static String toString(InputStream inputStream) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+        int i = bufferedReader.read();
+        while (i != -1) {
+            sb.append((char) i);
+            i = bufferedReader.read();
+        }
+        bufferedReader.close();
+        return sb.toString();
+    }
+}
--- a/test/jdk/sun/security/pkcs11/Cipher/TestKATForGCM.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/jdk/sun/security/pkcs11/Cipher/TestKATForGCM.java	Tue Oct 01 23:54:39 2019 -0400
@@ -30,12 +30,13 @@
  * @summary Known Answer Test for AES cipher with GCM mode support in
  * PKCS11 provider.
  */
-import java.security.*;
-import javax.crypto.*;
-import javax.crypto.spec.*;
-import java.math.*;
-
-import java.util.*;
+import java.security.GeneralSecurityException;
+import java.security.Provider;
+import java.util.Arrays;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
 
 public class TestKATForGCM extends PKCS11Test {
 
@@ -319,15 +320,21 @@
                 System.out.println("Test Passed!");
             }
         } catch (Exception e) {
-            double ver = getNSSInfo("nss");
-            if (ver < 3.251d && p.getName().contains("SunPKCS11-NSS") &&
-                System.getProperty("os.name").equals("SunOS")) {
-                // buggy behaviour from solaris on 11.2 OS (nss < 3.251)
-                System.out.println("Skipping: SunPKCS11-NSS: Old NSS: " + ver);
-                return; // OK
-            } else {
-                throw e;
+            System.out.println("Exception occured using " + p.getName() + " version " + p.getVersionStr());
+
+            if (isNSS(p)) {
+                double ver = getNSSInfo("nss");
+                String osName = System.getProperty("os.name");
+                if (ver < 3.251d && osName.equals("SunOS")) {
+                    // buggy behaviour from solaris on 11.2 OS (nss < 3.251)
+                    System.out.println("Skipping: SunPKCS11-NSS: Old NSS: " + ver);
+                    return; // OK
+                } else if (ver > 3.139 && ver < 3.15 && osName.equals("Linux")) {
+                    // warn about buggy behaviour on Linux with nss 3.14
+                    System.out.println("Warning: old NSS " + ver + " might be problematic, consider upgrading it");
+                }
             }
+            throw e;
         }
     }
 }
--- a/test/jtreg-ext/requires/VMProps.java	Tue Oct 01 18:53:13 2019 -0400
+++ b/test/jtreg-ext/requires/VMProps.java	Tue Oct 01 23:54:39 2019 -0400
@@ -235,7 +235,22 @@
      */
     protected String vmJvmci() {
         // builds with jvmci have this flag
-        return "" + (WB.getBooleanVMFlag("EnableJVMCI") != null);
+        if (WB.getBooleanVMFlag("EnableJVMCI") == null) {
+            return "false";
+        }
+
+        switch (GC.selected()) {
+            case Serial:
+            case Parallel:
+            case G1:
+                // These GCs are supported with JVMCI
+                return "true";
+            default:
+                break;
+        }
+
+        // Every other GC is not supported
+        return "false";
     }
 
     /**
@@ -356,7 +371,24 @@
         } else {
             jaotc = bin.resolve("jaotc");
         }
-        return "" + Files.exists(jaotc);
+
+        if (!Files.exists(jaotc)) {
+            // No jaotc => no AOT
+            return "false";
+        }
+
+        switch (GC.selected()) {
+            case Serial:
+            case Parallel:
+            case G1:
+                // These GCs are supported with AOT
+                return "true";
+            default:
+                break;
+        }
+
+        // Every other GC is not supported
+        return "false";
     }
 
     /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/math/FpRoundingBenchmark.java	Tue Oct 01 23:54:39 2019 -0400
@@ -0,0 +1,78 @@
+//
+// 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
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+//
+//
+package org.openjdk.bench.java.math;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FpRoundingBenchmark {
+
+  @Param({"1024"})
+  public int TESTSIZE;
+
+  public double[] DargV1;
+
+  public double[] Res;
+
+  public final double[] DspecialVals = {
+      0.0, -0.0, Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
+
+  @Setup(Level.Trial)
+  public void BmSetup() {
+    int i = 0;
+    Random r = new Random(1024);
+    DargV1 = new double[TESTSIZE];
+    Res = new double[TESTSIZE];
+
+    for (; i < DspecialVals.length; i++) {
+      DargV1[i] = DspecialVals[i];
+    }
+
+    for (; i < TESTSIZE; i++) {
+      DargV1[i] = r.nextDouble()*TESTSIZE;
+    }
+  }
+
+  @Benchmark
+  public void testceil(Blackhole bh) {
+    for (int i = 0; i < TESTSIZE; i++)
+      Res[i] = Math.ceil(DargV1[i]);
+  }
+
+  @Benchmark
+  public void testfloor(Blackhole bh) {
+    for (int i = 0; i < TESTSIZE; i++)
+      Res[i] = Math.floor(DargV1[i]);
+  }
+
+  @Benchmark
+  public void testrint(Blackhole bh) {
+    for (int i = 0; i < TESTSIZE; i++)
+      Res[i] = Math.rint(DargV1[i]);
+  }
+}