[llvm] [orc-rt] Add Windows virtual memory support (PR #224521)

Jared Wyles via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 22:23:27 PDT 2026


https://github.com/jaredwy updated https://github.com/llvm/llvm-project/pull/224521

>From dcc558aa7e32d712cc3ad22f3c5c6722293fb6b5 Mon Sep 17 00:00:00 2001
From: Jared Wyles <jared.wyles at gmail.com>
Date: Fri, 18 Sep 2026 15:29:23 +1000
Subject: [PATCH 1/2] [orc-rt] Add Windows page size detection

---
 orc-rt/test/regression/check-rt-process-info.test | 5 ++---
 orc-rt/test/regression/lit.cfg.py                 | 5 +++++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/orc-rt/test/regression/check-rt-process-info.test b/orc-rt/test/regression/check-rt-process-info.test
index d2e715e649298..d160f3d52ac04 100644
--- a/orc-rt/test/regression/check-rt-process-info.test
+++ b/orc-rt/test/regression/check-rt-process-info.test
@@ -1,7 +1,6 @@
 # RUN: orc-rt-process-info-check --print-triple --print-page-size --print-cpu-features \
-# RUN:   | FileCheck %s -DARCH=%host-arch -DOS=%host-os -DVERSION=%macos-product-version
+# RUN:   | FileCheck %s -DARCH=%host-arch -DOS=%host-os -DVERSION=%macos-product-version  -DVERSION=%host-page-size
 
 # CHECK:      [[ARCH]]-{{.*}}-[[OS]][[VERSION]]
-# CHECK-NEXT: {{4096|16384}}
+# CHECK-NEXT: [[host-page-size]]
 # CHECK-NEXT: {{^\+[a-z0-9_.]+(,\+[a-z0-9_.]+)*$}}
-
diff --git a/orc-rt/test/regression/lit.cfg.py b/orc-rt/test/regression/lit.cfg.py
index 3f28ecae5f2f3..98ca7410d382f 100644
--- a/orc-rt/test/regression/lit.cfg.py
+++ b/orc-rt/test/regression/lit.cfg.py
@@ -9,6 +9,7 @@
 from lit.llvm import llvm_config
 from lit.llvm.subst import ToolSubst
 import platform
+import mmap
 
 config.name = "ORC-RT"
 config.test_format = lit.formats.ShTest()
@@ -95,6 +96,10 @@ def add_logging_features():
 # reports against an independent source.
 config.substitutions.append(("%target-arch", config.target_triple.split("-")[0]))
 
+# Add the page size from mmap this allows us to avoid another if statement as
+# it would likely need ctypes for windows as it does not support sysconf
+config.substituions.append(('%host-page-size', mmap.PAGESIZE))
+
 # Add host OS and arch substitutions for host-detection tests.
 config.substitutions.append(("%host-arch", platform.machine()))
 if platform.system() == "Darwin":

>From f43398017fa5b0220e5382c161078606068a59e7 Mon Sep 17 00:00:00 2001
From: Jared Wyles <jared.wyles at gmail.com>
Date: Mon, 21 Sep 2026 22:05:53 +1000
Subject: [PATCH 2/2] [orc-rt] Add Windows virtual memory support

---
 .../support/sys/WinErrorToORCError.h          | 43 +++++++++++++
 orc-rt/lib/bedrock/sys/windows/Memory.cpp     | 64 +++++++++++++++++--
 .../bedrock/SimpleNativeMemoryMapTest.cpp     |  2 -
 .../sps/SimpleNativeMemoryMapSPSCITest.cpp    |  3 +-
 4 files changed, 101 insertions(+), 11 deletions(-)
 create mode 100644 orc-rt/include/orc-rt-internal/support/sys/WinErrorToORCError.h

diff --git a/orc-rt/include/orc-rt-internal/support/sys/WinErrorToORCError.h b/orc-rt/include/orc-rt-internal/support/sys/WinErrorToORCError.h
new file mode 100644
index 0000000000000..3ebbf6d3dcb91
--- /dev/null
+++ b/orc-rt/include/orc-rt-internal/support/sys/WinErrorToORCError.h
@@ -0,0 +1,43 @@
+#ifndef ORC_RT_INTERNAL_SUPPORT_SYS_WINERRORTOORCERROR_H
+#define ORC_RT_INTERNAL_SUPPORT_SYS_WINERRORTOORCERROR_H
+
+#include "orc-rt/support/Error.h"
+
+#include <string>
+#include <string_view>
+
+#include <windows.h>
+
+namespace orc_rt::sys {
+
+inline std::string getWindowsErrorMessage(DWORD ErrorCode) {
+  LPSTR Message = nullptr;
+
+  const DWORD Length = FormatMessageA(
+      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+          FORMAT_MESSAGE_IGNORE_INSERTS,
+      nullptr, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+      reinterpret_cast<LPSTR>(&Message), 0, nullptr);
+
+  if (!Length)
+    return "Windows error " + std::to_string(ErrorCode);
+
+  std::string Result(Message, Length);
+  LocalFree(Message);
+
+  while (!Result.empty() && (Result.back() == '\r' || Result.back() == '\n'))
+    Result.pop_back();
+
+  return Result;
+}
+
+inline Error generateErrorFromGetLastError(std::string_view Prefix) {
+  const DWORD ErrorCode = GetLastError();
+
+  return make_error<StringError>(std::string(Prefix) + ": " +
+                                 getWindowsErrorMessage(ErrorCode));
+}
+
+} // namespace orc_rt::sys
+
+#endif
diff --git a/orc-rt/lib/bedrock/sys/windows/Memory.cpp b/orc-rt/lib/bedrock/sys/windows/Memory.cpp
index 276fa1e292c23..6bfb060738370 100644
--- a/orc-rt/lib/bedrock/sys/windows/Memory.cpp
+++ b/orc-rt/lib/bedrock/sys/windows/Memory.cpp
@@ -1,4 +1,4 @@
-//===- Memory.cpp ---------------------------------------------------------===//
+//===--- Memory.cpp - Windows memory operations ---------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,19 +7,69 @@
 //===----------------------------------------------------------------------===//
 
 #include "orc-rt-internal/bedrock/sys/Memory.h"
+#include "orc-rt-internal/support/sys/WinErrorToORCError.h"
+
+#include <windows.h>
 
 namespace orc_rt::sys {
 
-Expected<void *> reserveMemory(uint64_t) {
-  return make_error<StringError>("Windows reserveMemory not implemented");
+namespace {
+
+DWORD getWindowsProtection(MemProt Prot) {
+  const bool Read = (Prot & MemProt::Read) != MemProt::None;
+  const bool Write = (Prot & MemProt::Write) != MemProt::None;
+  const bool Exec = (Prot & MemProt::Exec) != MemProt::None;
+
+  if (Exec) {
+    if (Write)
+      return PAGE_EXECUTE_READWRITE;
+    if (Read)
+      return PAGE_EXECUTE_READ;
+    return PAGE_EXECUTE;
+  }
+
+  if (Write)
+    return PAGE_READWRITE;
+  if (Read)
+    return PAGE_READONLY;
+
+  return PAGE_NOACCESS;
+}
+
+} // namespace
+
+Expected<void *> reserveMemory(uint64_t Size) {
+  void *Addr = VirtualAlloc(nullptr, static_cast<SIZE_T>(Size),
+                            MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+
+  if (!Addr)
+    return generateErrorFromGetLastError("VirtualAlloc failed");
+
+  return Addr;
 }
 
-Error releaseMemory(void *, uint64_t) {
-  return make_error<StringError>("Windows releaseMemory not implemented");
+Error releaseMemory(void *Base, uint64_t) {
+  // When MEM_RELEASE is specified, dwSize must be zero and Base must be the
+  // address returned by VirtualAlloc.
+  if (!VirtualFree(Base, 0, MEM_RELEASE))
+    return generateErrorFromGetLastError("VirtualFree failed");
+
+  return Error::success();
 }
 
-Error protectMemory(void *, uint64_t, MemProt) {
-  return make_error<StringError>("Windows protectMemory not implemented");
+Error protectMemory(void *Base, uint64_t Size, MemProt Prot) {
+  DWORD OldProtect = 0;
+
+  if (!VirtualProtect(Base, static_cast<SIZE_T>(Size),
+                      getWindowsProtection(Prot), &OldProtect))
+    return generateErrorFromGetLastError("VirtualProtect failed");
+
+  if ((Prot & MemProt::Exec) != MemProt::None &&
+      !FlushInstructionCache(GetCurrentProcess(), Base,
+                             static_cast<SIZE_T>(Size)))
+    return generateErrorFromGetLastError("FlushInstructionCache failed");
+
+  return Error::success();
 }
 
 } // namespace orc_rt::sys
diff --git a/orc-rt/test/unit/bedrock/SimpleNativeMemoryMapTest.cpp b/orc-rt/test/unit/bedrock/SimpleNativeMemoryMapTest.cpp
index 5cdcb2fe1e681..23d3cd7393d2b 100644
--- a/orc-rt/test/unit/bedrock/SimpleNativeMemoryMapTest.cpp
+++ b/orc-rt/test/unit/bedrock/SimpleNativeMemoryMapTest.cpp
@@ -9,7 +9,6 @@
 // Test SimpleNativeMemoryMap APIs.
 //
 //===----------------------------------------------------------------------===//
-#ifndef _WIN32
 
 #include "orc-rt/bedrock/SimpleNativeMemoryMap.h"
 #include "orc-rt/bedrock/Session.h"
@@ -323,4 +322,3 @@ TEST(SimpleNativeMemoryMapTest, ReserveInitializeDetachShutdown) {
 
   EXPECT_EQ(SentinelValue, 42);
 }
-#endif
diff --git a/orc-rt/test/unit/bedrock/sps/SimpleNativeMemoryMapSPSCITest.cpp b/orc-rt/test/unit/bedrock/sps/SimpleNativeMemoryMapSPSCITest.cpp
index d3ad5bef7edef..e455afb209574 100644
--- a/orc-rt/test/unit/bedrock/sps/SimpleNativeMemoryMapSPSCITest.cpp
+++ b/orc-rt/test/unit/bedrock/sps/SimpleNativeMemoryMapSPSCITest.cpp
@@ -9,7 +9,7 @@
 // Tests for SimpleNativeMemoryMap's SPS Controller Interface.
 //
 //===----------------------------------------------------------------------===//
-#ifndef _WIN32
+
 #include "orc-rt/bedrock/sps/SimpleNativeMemoryMapSPSCI.h"
 #include "orc-rt/bedrock/Session.h"
 #include "orc-rt/bedrock/SimpleNativeMemoryMap.h"
@@ -321,4 +321,3 @@ TEST_F(SimpleNativeMemoryMapSPSCITest, ReserveInitializeDetachShutdown) {
 
   EXPECT_EQ(SentinelValue, 42);
 }
-#endif



More information about the llvm-commits mailing list