changeset 57695:d4a477d5080f

8233299: Implementation: JEP 365: ZGC on Windows Reviewed-by: pliden, eosterlund
author stefank
date Thu, 07 Nov 2019 15:29:21 +0100
parents 1f2359ae7a86
children ac3c8cae4815
files make/autoconf/hotspot.m4 src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp src/hotspot/os/windows/gc/z/zBackingFile_windows.cpp src/hotspot/os/windows/gc/z/zBackingFile_windows.hpp src/hotspot/os/windows/gc/z/zInitialize_windows.cpp src/hotspot/os/windows/gc/z/zLargePages_windows.cpp src/hotspot/os/windows/gc/z/zMapper_windows.cpp src/hotspot/os/windows/gc/z/zMapper_windows.hpp src/hotspot/os/windows/gc/z/zNUMA_windows.cpp src/hotspot/os/windows/gc/z/zPhysicalMemoryBacking_windows.cpp src/hotspot/os/windows/gc/z/zPhysicalMemoryBacking_windows.hpp src/hotspot/os/windows/gc/z/zSyscall_windows.cpp src/hotspot/os/windows/gc/z/zSyscall_windows.hpp src/hotspot/os/windows/gc/z/zUtils_windows.cpp src/hotspot/os/windows/gc/z/zVirtualMemory_windows.cpp
diffstat 15 files changed, 1200 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/make/autoconf/hotspot.m4	Tue Dec 03 10:40:58 2019 +0100
+++ b/make/autoconf/hotspot.m4	Thu Nov 07 15:29:21 2019 +0100
@@ -347,7 +347,8 @@
   # Only enable ZGC on supported platforms
   AC_MSG_CHECKING([if zgc can be built])
   if (test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK_TARGET_CPU" = "xx86_64") || \
-     (test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK_TARGET_CPU" = "xaarch64") ||
+     (test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK_TARGET_CPU" = "xaarch64") || \
+     (test "x$OPENJDK_TARGET_OS" = "xwindows" && test "x$OPENJDK_TARGET_CPU" = "xx86_64") || \
      (test "x$OPENJDK_TARGET_OS" = "xmacosx" && test "x$OPENJDK_TARGET_CPU" = "xx86_64"); then
     AC_MSG_RESULT([yes])
   else
--- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp	Tue Dec 03 10:40:58 2019 +0100
+++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -517,8 +517,11 @@
     // Sort by size, largest first
     _xmm_registers.sort(xmm_compare_register_size);
 
+    // On Windows, the caller reserves stack space for spilling register arguments
+    const int arg_spill_size = frame::arg_reg_save_area_bytes;
+
     // Stack pointer must be 16 bytes aligned for the call
-    _spill_offset = _spill_size = align_up(xmm_spill_size + gp_spill_size, 16);
+    _spill_offset = _spill_size = align_up(xmm_spill_size + gp_spill_size + arg_spill_size, 16);
   }
 
 public:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zBackingFile_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zBackingFile_windows.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zGranuleMap.inline.hpp"
+#include "gc/z/zMapper_windows.hpp"
+#include "logging/log.hpp"
+#include "runtime/globals.hpp"
+#include "utilities/debug.hpp"
+
+// The backing file commits and uncommits physical memory, that can be
+// multi-mapped into the virtual address space. To support fine-graned
+// committing and uncommitting, each ZGranuleSize chunked is mapped to
+// a separate paging file mapping.
+
+ZBackingFile::ZBackingFile() :
+    _handles(MaxHeapSize),
+    _size(0) {}
+
+size_t ZBackingFile::size() const {
+  return _size;
+}
+
+HANDLE ZBackingFile::get_handle(uintptr_t offset) const {
+  HANDLE const handle = _handles.get(offset);
+  assert(handle != 0, "Should be set");
+  return handle;
+}
+
+void ZBackingFile::put_handle(uintptr_t offset, HANDLE handle) {
+  assert(handle != INVALID_HANDLE_VALUE, "Invalid handle");
+  assert(_handles.get(offset) == 0, "Should be cleared");
+  _handles.put(offset, handle);
+}
+
+void ZBackingFile::clear_handle(uintptr_t offset) {
+  assert(_handles.get(offset) != 0, "Should be set");
+  _handles.put(offset, 0);
+}
+
+size_t ZBackingFile::commit_from_paging_file(size_t offset, size_t size) {
+  for (size_t i = 0; i < size; i += ZGranuleSize) {
+    HANDLE const handle = ZMapper::create_and_commit_paging_file_mapping(ZGranuleSize);
+    if (handle == 0) {
+      return i;
+    }
+
+    put_handle(offset + i, handle);
+  }
+
+  return size;
+}
+
+size_t ZBackingFile::uncommit_from_paging_file(size_t offset, size_t size) {
+  for (size_t i = 0; i < size; i += ZGranuleSize) {
+    HANDLE const handle = get_handle(offset + i);
+    clear_handle(offset + i);
+    ZMapper::close_paging_file_mapping(handle);
+  }
+
+  return size;
+}
+
+size_t ZBackingFile::commit(size_t offset, size_t length) {
+  log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
+                      offset / M, (offset + length) / M, length / M);
+
+  const size_t committed = commit_from_paging_file(offset, length);
+
+  const size_t end = offset + committed;
+  if (end > _size) {
+    // Update size
+    _size = end;
+  }
+
+  return committed;
+}
+
+size_t ZBackingFile::uncommit(size_t offset, size_t length) {
+  log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
+                      offset / M, (offset + length) / M, length / M);
+
+  return uncommit_from_paging_file(offset, length);
+}
+
+void ZBackingFile::map(uintptr_t addr, size_t size, size_t offset) const {
+  assert(is_aligned(offset, ZGranuleSize), "Misaligned");
+  assert(is_aligned(addr, ZGranuleSize), "Misaligned");
+  assert(is_aligned(size, ZGranuleSize), "Misaligned");
+
+  for (size_t i = 0; i < size; i += ZGranuleSize) {
+    HANDLE const handle = get_handle(offset + i);
+    ZMapper::map_view_replace_placeholder(handle, 0 /* offset */, addr + i, ZGranuleSize);
+  }
+}
+
+void ZBackingFile::unmap(uintptr_t addr, size_t size) const {
+  assert(is_aligned(addr, ZGranuleSize), "Misaligned");
+  assert(is_aligned(size, ZGranuleSize), "Misaligned");
+
+  for (size_t i = 0; i < size; i += ZGranuleSize) {
+    ZMapper::unmap_view_preserve_placeholder(addr + i, ZGranuleSize);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zBackingFile_windows.hpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef OS_WINDOWS_GC_Z_ZBACKINGFILE_WINDOWS_HPP
+#define OS_WINDOWS_GC_Z_ZBACKINGFILE_WINDOWS_HPP
+
+#include "gc/z/zGranuleMap.hpp"
+#include "memory/allocation.hpp"
+
+#include <Windows.h>
+
+class ZBackingFile {
+private:
+  ZGranuleMap<HANDLE> _handles;
+  size_t              _size;
+
+  HANDLE get_handle(uintptr_t offset) const;
+  void put_handle(uintptr_t offset, HANDLE handle);
+  void clear_handle(uintptr_t offset);
+
+  size_t commit_from_paging_file(size_t offset, size_t size);
+  size_t uncommit_from_paging_file(size_t offset, size_t size);
+
+public:
+  ZBackingFile();
+
+  size_t size() const;
+
+  size_t commit(size_t offset, size_t length);
+  size_t uncommit(size_t offset, size_t length);
+
+  void map(uintptr_t addr, size_t size, size_t offset) const;
+  void unmap(uintptr_t addr, size_t size) const;
+};
+
+#endif // OS_WINDOWS_GC_Z_ZBACKINGFILE_WINDOWS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zInitialize_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zInitialize.hpp"
+#include "gc/z/zSyscall_windows.hpp"
+
+void ZInitialize::initialize_os() {
+  ZSyscall::initialize();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zLargePages_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zLargePages.hpp"
+
+void ZLargePages::initialize_platform() {
+  _state = Disabled;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zMapper_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,254 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zMapper_windows.hpp"
+#include "gc/z/zSyscall_windows.hpp"
+#include "logging/log.hpp"
+#include "utilities/debug.hpp"
+
+#include <Windows.h>
+
+// Memory reservation, commit, views, and placeholders.
+//
+// To be able to up-front reserve address space for the heap views, and later
+// multi-map the heap views to the same physical memory, without ever losing the
+// reservation of the reserved address space, we use "placeholders".
+//
+// These placeholders block out the address space from being used by other parts
+// of the process. To commit memory in this address space, the placeholder must
+// be replaced by anonymous memory, or replaced by mapping a view against a
+// paging file mapping. We use the later to support multi-mapping.
+//
+// We want to be able to dynamically commit and uncommit the physical memory of
+// the heap (and also unmap ZPages), in granules of ZGranuleSize bytes. There is
+// no way to grow and shrink the committed memory of a paging file mapping.
+// Therefore, we create multiple granule-sized page file mappings. The memory is
+// committed by creating a page file mapping, map a view against it, commit the
+// memory, unmap the view. The memory will stay committed until all views are
+// unmapped, and the paging file mapping handle is closed.
+//
+// When replacing a placeholder address space reservation with a mapped view
+// against a paging file mapping, the virtual address space must exactly match
+// an existing placeholder's address and size. Therefore we only deal with
+// granule-sized placeholders at this layer. Higher layers that keep track of
+// reserved available address space can (and will) coalesce placeholders, but
+// they will be split before being used.
+
+#define fatal_error(msg, addr, size)                  \
+  fatal(msg ": " PTR_FORMAT " " SIZE_FORMAT "M (%d)", \
+        (addr), (size) / M, GetLastError())
+
+uintptr_t ZMapper::reserve(uintptr_t addr, size_t size) {
+  void* const res = ZSyscall::VirtualAlloc2(
+    GetCurrentProcess(),                   // Process
+    (void*)addr,                           // BaseAddress
+    size,                                  // Size
+    MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, // AllocationType
+    PAGE_NOACCESS,                         // PageProtection
+    NULL,                                  // ExtendedParameters
+    0                                      // ParameterCount
+    );
+
+  // Caller responsible for error handling
+  return (uintptr_t)res;
+}
+
+void ZMapper::unreserve(uintptr_t addr, size_t size) {
+  const bool res = ZSyscall::VirtualFreeEx(
+    GetCurrentProcess(), // hProcess
+    (void*)addr,         // lpAddress
+    size,                // dwSize
+    MEM_RELEASE          // dwFreeType
+    );
+
+  if (!res) {
+    fatal_error("Failed to unreserve memory", addr, size);
+  }
+}
+
+HANDLE ZMapper::create_paging_file_mapping(size_t size) {
+  // Create mapping with SEC_RESERVE instead of SEC_COMMIT.
+  //
+  // We use MapViewOfFile3 for two different reasons:
+  //  1) When commiting memory for the created paging file
+  //  2) When mapping a view of the memory created in (2)
+  //
+  // The non-platform code is only setup to deal with out-of-memory
+  // errors in (1). By using SEC_RESERVE, we prevent MapViewOfFile3
+  // from failing because of "commit limit" checks. To actually commit
+  // memory in (1), a call to VirtualAlloc2 is done.
+
+  HANDLE const res = ZSyscall::CreateFileMappingW(
+    INVALID_HANDLE_VALUE,         // hFile
+    NULL,                         // lpFileMappingAttribute
+    PAGE_READWRITE | SEC_RESERVE, // flProtect
+    size >> 32,                   // dwMaximumSizeHigh
+    size & 0xFFFFFFFF,            // dwMaximumSizeLow
+    NULL                          // lpName
+    );
+
+  // Caller responsible for error handling
+  return res;
+}
+
+bool ZMapper::commit_paging_file_mapping(HANDLE file_handle, uintptr_t file_offset, size_t size) {
+  const uintptr_t addr = map_view_no_placeholder(file_handle, file_offset, size);
+  if (addr == 0) {
+    log_error(gc)("Failed to map view of paging file mapping (%d)", GetLastError());
+    return false;
+  }
+
+  const uintptr_t res = commit(addr, size);
+  if (res != addr) {
+    log_error(gc)("Failed to commit memory (%d)", GetLastError());
+  }
+
+  unmap_view_no_placeholder(addr, size);
+
+  return res == addr;
+}
+
+uintptr_t ZMapper::map_view_no_placeholder(HANDLE file_handle, uintptr_t file_offset, size_t size) {
+  void* const res = ZSyscall::MapViewOfFile3(
+    file_handle,         // FileMapping
+    GetCurrentProcess(), // ProcessHandle
+    NULL,                // BaseAddress
+    file_offset,         // Offset
+    size,                // ViewSize
+    0,                   // AllocationType
+    PAGE_NOACCESS,       // PageProtection
+    NULL,                // ExtendedParameters
+    0                    // ParameterCount
+    );
+
+  // Caller responsible for error handling
+  return (uintptr_t)res;
+}
+
+void ZMapper::unmap_view_no_placeholder(uintptr_t addr, size_t size) {
+  const bool res = ZSyscall::UnmapViewOfFile2(
+    GetCurrentProcess(), // ProcessHandle
+    (void*)addr,         // BaseAddress
+    0                    // UnmapFlags
+    );
+
+  if (!res) {
+    fatal_error("Failed to unmap memory", addr, size);
+  }
+}
+
+uintptr_t ZMapper::commit(uintptr_t addr, size_t size) {
+  void* const res = ZSyscall::VirtualAlloc2(
+    GetCurrentProcess(), // Process
+    (void*)addr,         // BaseAddress
+    size,                // Size
+    MEM_COMMIT,          // AllocationType
+    PAGE_NOACCESS,       // PageProtection
+    NULL,                // ExtendedParameters
+    0                    // ParameterCount
+    );
+
+  // Caller responsible for error handling
+  return (uintptr_t)res;
+}
+
+HANDLE ZMapper::create_and_commit_paging_file_mapping(size_t size) {
+  HANDLE const file_handle = create_paging_file_mapping(size);
+  if (file_handle == 0) {
+    log_error(gc)("Failed to create paging file mapping (%d)", GetLastError());
+    return 0;
+  }
+
+  const bool res = commit_paging_file_mapping(file_handle, 0 /* file_offset */, size);
+  if (!res) {
+    close_paging_file_mapping(file_handle);
+    return 0;
+  }
+
+  return file_handle;
+}
+
+void ZMapper::close_paging_file_mapping(HANDLE file_handle) {
+  const bool res = CloseHandle(
+    file_handle // hObject
+    );
+
+  if (!res) {
+    fatal("Failed to close paging file handle (%d)", GetLastError());
+  }
+}
+
+void ZMapper::split_placeholder(uintptr_t addr, size_t size) {
+  const bool res = VirtualFree(
+    (void*)addr,                           // lpAddress
+    size,                                  // dwSize
+    MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER // dwFreeType
+    );
+
+  if (!res) {
+    fatal_error("Failed to split placeholder", addr, size);
+  }
+}
+
+void ZMapper::coalesce_placeholders(uintptr_t addr, size_t size) {
+  const bool res = VirtualFree(
+    (void*)addr,                            // lpAddress
+    size,                                   // dwSize
+    MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS // dwFreeType
+    );
+
+  if (!res) {
+    fatal_error("Failed to coalesce placeholders", addr, size);
+  }
+}
+
+void ZMapper::map_view_replace_placeholder(HANDLE file_handle, uintptr_t file_offset, uintptr_t addr, size_t size) {
+  void* const res = ZSyscall::MapViewOfFile3(
+    file_handle,             // FileMapping
+    GetCurrentProcess(),     // ProcessHandle
+    (void*)addr,             // BaseAddress
+    file_offset,             // Offset
+    size,                    // ViewSize
+    MEM_REPLACE_PLACEHOLDER, // AllocationType
+    PAGE_READWRITE,          // PageProtection
+    NULL,                    // ExtendedParameters
+    0                        // ParameterCount
+    );
+
+  if (res == NULL) {
+    fatal_error("Failed to map memory", addr, size);
+  }
+}
+
+void ZMapper::unmap_view_preserve_placeholder(uintptr_t addr, size_t size) {
+  const bool res = ZSyscall::UnmapViewOfFile2(
+    GetCurrentProcess(),     // ProcessHandle
+    (void*)addr,             // BaseAddress
+    MEM_PRESERVE_PLACEHOLDER // UnmapFlags
+    );
+
+  if (!res) {
+    fatal_error("Failed to unmap memory", addr, size);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zMapper_windows.hpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#ifndef OS_WINDOWS_GC_Z_ZMAPPER_WINDOWS_HPP
+#define OS_WINDOWS_GC_Z_ZMAPPER_WINDOWS_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+#include <Windows.h>
+
+class ZMapper : public AllStatic {
+private:
+  // Create paging file mapping
+  static HANDLE create_paging_file_mapping(size_t size);
+
+  // Commit paging file mapping
+  static bool commit_paging_file_mapping(HANDLE file_handle, uintptr_t file_offset, size_t size);
+
+  // Map a view anywhere without a placeholder
+  static uintptr_t map_view_no_placeholder(HANDLE file_handle, uintptr_t file_offset, size_t size);
+
+  // Unmap a view without preserving a placeholder
+  static void unmap_view_no_placeholder(uintptr_t addr, size_t size);
+
+  // Commit memory covering the given virtual address range
+  static uintptr_t commit(uintptr_t addr, size_t size);
+
+public:
+  // Reserve memory with a placeholder
+  static uintptr_t reserve(uintptr_t addr, size_t size);
+
+  // Unreserve memory
+  static void unreserve(uintptr_t addr, size_t size);
+
+  // Create and commit paging file mapping
+  static HANDLE create_and_commit_paging_file_mapping(size_t size);
+
+  // Close paging file mapping
+  static void close_paging_file_mapping(HANDLE file_handle);
+
+  // Split a placeholder
+  //
+  // A view can only replace an entire placeholder, so placeholders need to be
+  // split and coalesced to be the exact size of the new views.
+  // [addr, addr + size) needs to be a proper sub-placeholder of an existing
+  // placeholder.
+  static void split_placeholder(uintptr_t addr, size_t size);
+
+  // Coalesce a placeholder
+  //
+  // [addr, addr + size) is the new placeholder. A sub-placeholder needs to
+  // exist within that range.
+  static void coalesce_placeholders(uintptr_t addr, size_t size);
+
+  // Map a view of the file handle and replace the placeholder covering the
+  // given virtual address range
+  static void map_view_replace_placeholder(HANDLE file_handle, uintptr_t file_offset, uintptr_t addr, size_t size);
+
+  // Unmap the view and reinstate a placeholder covering the given virtual
+  // address range
+  static void unmap_view_preserve_placeholder(uintptr_t addr, size_t size);
+};
+
+#endif // OS_WINDOWS_GC_Z_ZMAPPER_WINDOWS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zNUMA.hpp"
+
+void ZNUMA::initialize_platform() {
+  _enabled = false;
+}
+
+uint32_t ZNUMA::count() {
+  return 1;
+}
+
+uint32_t ZNUMA::id() {
+  return 0;
+}
+
+uint32_t ZNUMA::memory_id(uintptr_t addr) {
+  // NUMA support not enabled, assume everything belongs to node zero
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zPhysicalMemoryBacking_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zLargePages.inline.hpp"
+#include "gc/z/zMapper_windows.hpp"
+#include "gc/z/zPhysicalMemory.inline.hpp"
+#include "gc/z/zPhysicalMemoryBacking_windows.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/init.hpp"
+#include "runtime/os.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+bool ZPhysicalMemoryBacking::is_initialized() const {
+  return true;
+}
+
+void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
+  // Does nothing
+}
+
+bool ZPhysicalMemoryBacking::supports_uncommit() {
+  assert(!is_init_completed(), "Invalid state");
+  assert(_file.size() >= ZGranuleSize, "Invalid size");
+
+  // Test if uncommit is supported by uncommitting and then re-committing a granule
+  return commit(uncommit(ZGranuleSize)) == ZGranuleSize;
+}
+
+size_t ZPhysicalMemoryBacking::commit(size_t size) {
+  size_t committed = 0;
+
+  // Fill holes in the backing file
+  while (committed < size) {
+    size_t allocated = 0;
+    const size_t remaining = size - committed;
+    const uintptr_t start = _uncommitted.alloc_from_front_at_most(remaining, &allocated);
+    if (start == UINTPTR_MAX) {
+      // No holes to commit
+      break;
+    }
+
+    // Try commit hole
+    const size_t filled = _file.commit(start, allocated);
+    if (filled > 0) {
+      // Successful or partialy successful
+      _committed.free(start, filled);
+      committed += filled;
+    }
+    if (filled < allocated) {
+      // Failed or partialy failed
+      _uncommitted.free(start + filled, allocated - filled);
+      return committed;
+    }
+  }
+
+  // Expand backing file
+  if (committed < size) {
+    const size_t remaining = size - committed;
+    const uintptr_t start = _file.size();
+    const size_t expanded = _file.commit(start, remaining);
+    if (expanded > 0) {
+      // Successful or partialy successful
+      _committed.free(start, expanded);
+      committed += expanded;
+    }
+  }
+
+  return committed;
+}
+
+size_t ZPhysicalMemoryBacking::uncommit(size_t size) {
+  size_t uncommitted = 0;
+
+  // Punch holes in backing file
+  while (uncommitted < size) {
+    size_t allocated = 0;
+    const size_t remaining = size - uncommitted;
+    const uintptr_t start = _committed.alloc_from_back_at_most(remaining, &allocated);
+    assert(start != UINTPTR_MAX, "Allocation should never fail");
+
+    // Try punch hole
+    const size_t punched = _file.uncommit(start, allocated);
+    if (punched > 0) {
+      // Successful or partialy successful
+      _uncommitted.free(start, punched);
+      uncommitted += punched;
+    }
+    if (punched < allocated) {
+      // Failed or partialy failed
+      _committed.free(start + punched, allocated - punched);
+      return uncommitted;
+    }
+  }
+
+  return uncommitted;
+}
+
+ZPhysicalMemory ZPhysicalMemoryBacking::alloc(size_t size) {
+  assert(is_aligned(size, ZGranuleSize), "Invalid size");
+
+  ZPhysicalMemory pmem;
+
+  // Allocate segments
+  for (size_t allocated = 0; allocated < size; allocated += ZGranuleSize) {
+    const uintptr_t start = _committed.alloc_from_front(ZGranuleSize);
+    assert(start != UINTPTR_MAX, "Allocation should never fail");
+    pmem.add_segment(ZPhysicalMemorySegment(start, ZGranuleSize));
+  }
+
+  return pmem;
+}
+
+void ZPhysicalMemoryBacking::free(const ZPhysicalMemory& pmem) {
+  const size_t nsegments = pmem.nsegments();
+
+  // Free segments
+  for (size_t i = 0; i < nsegments; i++) {
+    const ZPhysicalMemorySegment& segment = pmem.segment(i);
+    _committed.free(segment.start(), segment.size());
+  }
+}
+
+void ZPhysicalMemoryBacking::pretouch_view(uintptr_t addr, size_t size) const {
+  const size_t page_size = ZLargePages::is_explicit() ? os::large_page_size() : os::vm_page_size();
+  os::pretouch_memory((void*)addr, (void*)(addr + size), page_size);
+}
+
+void ZPhysicalMemoryBacking::map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const {
+  const size_t nsegments = pmem.nsegments();
+  size_t size = 0;
+
+  // Map segments
+  for (size_t i = 0; i < nsegments; i++) {
+    const ZPhysicalMemorySegment& segment = pmem.segment(i);
+    _file.map(addr + size, segment.size(), segment.start());
+    size += segment.size();
+  }
+
+  // Pre-touch memory
+  if (pretouch) {
+    pretouch_view(addr, size);
+  }
+}
+
+void ZPhysicalMemoryBacking::unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const {
+  _file.unmap(addr, pmem.size());
+}
+
+uintptr_t ZPhysicalMemoryBacking::nmt_address(uintptr_t offset) const {
+  // From an NMT point of view we treat the first heap view (marked0) as committed
+  return ZAddress::marked0(offset);
+}
+
+void ZPhysicalMemoryBacking::map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
+  if (ZVerifyViews) {
+    // Map good view
+    map_view(pmem, ZAddress::good(offset), AlwaysPreTouch);
+  } else {
+    // Map all views
+    map_view(pmem, ZAddress::marked0(offset), AlwaysPreTouch);
+    map_view(pmem, ZAddress::marked1(offset), AlwaysPreTouch);
+    map_view(pmem, ZAddress::remapped(offset), AlwaysPreTouch);
+  }
+}
+
+void ZPhysicalMemoryBacking::unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
+  if (ZVerifyViews) {
+    // Unmap good view
+    unmap_view(pmem, ZAddress::good(offset));
+  } else {
+    // Unmap all views
+    unmap_view(pmem, ZAddress::marked0(offset));
+    unmap_view(pmem, ZAddress::marked1(offset));
+    unmap_view(pmem, ZAddress::remapped(offset));
+  }
+}
+
+void ZPhysicalMemoryBacking::debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
+  // Map good view
+  assert(ZVerifyViews, "Should be enabled");
+  map_view(pmem, ZAddress::good(offset), false /* pretouch */);
+}
+
+void ZPhysicalMemoryBacking::debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
+  // Unmap good view
+  assert(ZVerifyViews, "Should be enabled");
+  unmap_view(pmem, ZAddress::good(offset));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zPhysicalMemoryBacking_windows.hpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef OS_WINDOWS_GC_Z_ZPHYSICALMEMORYBACKING_WINDOWS_HPP
+#define OS_WINDOWS_GC_Z_ZPHYSICALMEMORYBACKING_WINDOWS_HPP
+
+#include "gc/z/zBackingFile_windows.hpp"
+#include "gc/z/zMemory.hpp"
+
+class ZPhysicalMemory;
+
+class ZPhysicalMemoryBacking {
+private:
+  ZBackingFile   _file;
+  ZMemoryManager _committed;
+  ZMemoryManager _uncommitted;
+
+  void pretouch_view(uintptr_t addr, size_t size) const;
+  void map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const;
+  void unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const;
+
+public:
+  bool is_initialized() const;
+
+  void warn_commit_limits(size_t max) const;
+  bool supports_uncommit();
+
+  size_t commit(size_t size);
+  size_t uncommit(size_t size);
+
+  ZPhysicalMemory alloc(size_t size);
+  void free(const ZPhysicalMemory& pmem);
+
+  uintptr_t nmt_address(uintptr_t offset) const;
+
+  void map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+
+  void debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+};
+
+#endif // OS_WINDOWS_GC_Z_ZPHYSICALMEMORYBACKING_WINDOWS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zSyscall_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zSyscall_windows.hpp"
+#include "logging/log.hpp"
+#include "runtime/java.hpp"
+#include "runtime/os.hpp"
+
+ZSyscall::CreateFileMappingWFn ZSyscall::CreateFileMappingW;
+ZSyscall::VirtualAlloc2Fn ZSyscall::VirtualAlloc2;
+ZSyscall::VirtualFreeExFn ZSyscall::VirtualFreeEx;
+ZSyscall::MapViewOfFile3Fn ZSyscall::MapViewOfFile3;
+ZSyscall::UnmapViewOfFile2Fn ZSyscall::UnmapViewOfFile2;
+
+template <typename Fn>
+static void lookup_symbol(Fn*& fn, const char* library, const char* symbol) {
+  char ebuf[1024];
+  void* const handle = os::dll_load(library, ebuf, sizeof(ebuf));
+  if (handle == NULL) {
+    log_error(gc)("Failed to load library: %s", library);
+    vm_exit_during_initialization("ZGC requires Windows version 1803 or later");
+  }
+
+  fn = reinterpret_cast<Fn*>(os::dll_lookup(handle, symbol));
+  if (fn == NULL) {
+    log_error(gc)("Failed to lookup symbol: %s", symbol);
+    vm_exit_during_initialization("ZGC requires Windows version 1803 or later");
+  }
+}
+
+void ZSyscall::initialize() {
+  lookup_symbol(CreateFileMappingW, "KernelBase", "CreateFileMappingW");
+  lookup_symbol(VirtualAlloc2,      "KernelBase", "VirtualAlloc2");
+  lookup_symbol(VirtualFreeEx,      "KernelBase", "VirtualFreeEx");
+  lookup_symbol(MapViewOfFile3,     "KernelBase", "MapViewOfFile3");
+  lookup_symbol(UnmapViewOfFile2,   "KernelBase", "UnmapViewOfFile2");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zSyscall_windows.hpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#ifndef OS_WINDOWS_GC_Z_ZSYSCALL_WINDOWS_HPP
+#define OS_WINDOWS_GC_Z_ZSYSCALL_WINDOWS_HPP
+
+#include "utilities/globalDefinitions.hpp"
+
+#include <Windows.h>
+#include <Memoryapi.h>
+
+class ZSyscall {
+private:
+  typedef HANDLE (*CreateFileMappingWFn)(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCWSTR);
+  typedef PVOID (*VirtualAlloc2Fn)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG);
+  typedef BOOL (*VirtualFreeExFn)(HANDLE, LPVOID, SIZE_T, DWORD);
+  typedef PVOID (*MapViewOfFile3Fn)(HANDLE, HANDLE, PVOID, ULONG64, SIZE_T, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG);
+  typedef BOOL (*UnmapViewOfFile2Fn)(HANDLE, PVOID, ULONG);
+
+public:
+  static CreateFileMappingWFn CreateFileMappingW;
+  static VirtualAlloc2Fn      VirtualAlloc2;
+  static VirtualFreeExFn      VirtualFreeEx;
+  static MapViewOfFile3Fn     MapViewOfFile3;
+  static UnmapViewOfFile2Fn   UnmapViewOfFile2;
+
+  static void initialize();
+};
+
+#endif // OS_WINDOWS_GC_Z_ZSYSCALL_WINDOWS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zUtils_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zUtils.hpp"
+#include "utilities/debug.hpp"
+
+#include <malloc.h>
+
+uintptr_t ZUtils::alloc_aligned(size_t alignment, size_t size) {
+  void* const res = _aligned_malloc(size, alignment);
+
+  if (res == NULL) {
+    fatal("_aligned_malloc failed");
+  }
+
+  memset(res, 0, size);
+
+  return (uintptr_t)res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/windows/gc/z/zVirtualMemory_windows.cpp	Thu Nov 07 15:29:21 2019 +0100
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zMapper_windows.hpp"
+#include "gc/z/zVirtualMemory.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+static void split_placeholder(uintptr_t start, size_t size) {
+  ZMapper::split_placeholder(ZAddress::marked0(start), size);
+  ZMapper::split_placeholder(ZAddress::marked1(start), size);
+  ZMapper::split_placeholder(ZAddress::remapped(start), size);
+}
+
+static void coalesce_placeholders(uintptr_t start, size_t size) {
+  ZMapper::coalesce_placeholders(ZAddress::marked0(start), size);
+  ZMapper::coalesce_placeholders(ZAddress::marked1(start), size);
+  ZMapper::coalesce_placeholders(ZAddress::remapped(start), size);
+}
+
+static void split_into_placeholder_granules(uintptr_t start, size_t size) {
+  for (uintptr_t addr = start; addr < start + size; addr += ZGranuleSize) {
+    split_placeholder(addr, ZGranuleSize);
+  }
+}
+
+static void coalesce_into_one_placeholder(uintptr_t start, size_t size) {
+  assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
+
+  if (size > ZGranuleSize) {
+    coalesce_placeholders(start, size);
+  }
+}
+
+static void create_callback(const ZMemory* area) {
+  assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
+  coalesce_into_one_placeholder(area->start(), area->size());
+}
+
+static void destroy_callback(const ZMemory* area) {
+  assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
+  // Don't try split the last granule - VirtualFree will fail
+  split_into_placeholder_granules(area->start(), area->size() - ZGranuleSize);
+}
+
+static void shrink_from_front_callback(const ZMemory* area, size_t size) {
+  assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
+  split_into_placeholder_granules(area->start(), size);
+}
+
+static void shrink_from_back_callback(const ZMemory* area, size_t size) {
+  assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
+  // Don't try split the last granule - VirtualFree will fail
+  split_into_placeholder_granules(area->end() - size, size - ZGranuleSize);
+}
+
+static void grow_from_front_callback(const ZMemory* area, size_t size) {
+  assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
+  coalesce_into_one_placeholder(area->start() - size, area->size() + size);
+}
+
+static void grow_from_back_callback(const ZMemory* area, size_t size) {
+  assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
+  coalesce_into_one_placeholder(area->start(), area->size() + size);
+}
+
+void ZVirtualMemoryManager::initialize_os() {
+  // Each reserved virtual memory address area registered in _manager is
+  // exactly covered by a single placeholder. Callbacks are installed so
+  // that whenever a memory area changes, the corresponding placeholder
+  // is adjusted.
+  //
+  // The create and grow callbacks are called when virtual memory is
+  // returned to the memory manager. The new memory area is then covered
+  // by a new single placeholder.
+  //
+  // The destroy and shrink callbacks are called when virtual memory is
+  // allocated from the memory manager. The memory area is then is split
+  // into granule-sized placeholders.
+  //
+  // See comment in zMapper_windows.cpp explaining why placeholders are
+  // split into ZGranuleSize sized placeholders.
+
+  ZMemoryManager::Callbacks callbacks;
+
+  callbacks._create = &create_callback;
+  callbacks._destroy = &destroy_callback;
+  callbacks._shrink_from_front = &shrink_from_front_callback;
+  callbacks._shrink_from_back = &shrink_from_back_callback;
+  callbacks._grow_from_front = &grow_from_front_callback;
+  callbacks._grow_from_back = &grow_from_back_callback;
+
+  _manager.register_callbacks(callbacks);
+}
+
+bool ZVirtualMemoryManager::reserve_contiguous_platform(uintptr_t start, size_t size) {
+  assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
+
+  // Reserve address views
+  const uintptr_t marked0 = ZAddress::marked0(start);
+  const uintptr_t marked1 = ZAddress::marked1(start);
+  const uintptr_t remapped = ZAddress::remapped(start);
+
+  // Reserve address space
+  if (ZMapper::reserve(marked0, size) != marked0) {
+    return false;
+  }
+
+  if (ZMapper::reserve(marked1, size) != marked1) {
+    ZMapper::unreserve(marked0, size);
+    return false;
+  }
+
+  if (ZMapper::reserve(remapped, size) != remapped) {
+    ZMapper::unreserve(marked0, size);
+    ZMapper::unreserve(marked1, size);
+    return false;
+  }
+
+  // Register address views with native memory tracker
+  nmt_reserve(marked0, size);
+  nmt_reserve(marked1, size);
+  nmt_reserve(remapped, size);
+
+  return true;
+}