From 64ec068ca1e9581a57672cd6377cd45f7bd0abb7 Mon Sep 17 00:00:00 2001
From: Chris Denton <chris@chrisdenton.dev>
Date: Fri, 18 Oct 2024 10:57:45 +0000
Subject: [PATCH] Revert using `HEAP` static in Windows alloc

---
 library/std/src/sys/alloc/windows.rs | 69 +++++-----------------------
 1 file changed, 12 insertions(+), 57 deletions(-)

diff --git a/library/std/src/sys/alloc/windows.rs b/library/std/src/sys/alloc/windows.rs
index a77dda6e817ba..7e2402afab972 100644
--- a/library/std/src/sys/alloc/windows.rs
+++ b/library/std/src/sys/alloc/windows.rs
@@ -3,7 +3,6 @@ use crate::alloc::{GlobalAlloc, Layout, System};
 use crate::ffi::c_void;
 use crate::mem::MaybeUninit;
 use crate::ptr;
-use crate::sync::atomic::{AtomicPtr, Ordering};
 use crate::sys::c;
 
 #[cfg(test)]
@@ -81,40 +80,18 @@ windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
 // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
 windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const c_void) -> c::BOOL);
 
-// Cached handle to the default heap of the current process.
-// Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed.
-static HEAP: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
-
-// Get a handle to the default heap of the current process, or null if the operation fails.
-// If this operation is successful, `HEAP` will be successfully initialized and contain
-// a non-null handle returned by `GetProcessHeap`.
-#[inline]
-fn init_or_get_process_heap() -> c::HANDLE {
-    // `HEAP` has not yet been successfully initialized
-    let heap = unsafe { GetProcessHeap() };
-    if !heap.is_null() {
-        // SAFETY: No locking is needed because within the same process,
-        // successful calls to `GetProcessHeap` will always return the same value, even on different threads.
-        HEAP.store(heap, Ordering::Release);
-
-        // SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap`
-        heap
-    } else {
-        // Could not get the current process heap.
-        ptr::null_mut()
-    }
+fn get_process_heap() -> *mut c_void {
+    // SAFETY: GetProcessHeap simply returns a valid handle or NULL so is always safe to call.
+    unsafe { GetProcessHeap() }
 }
 
-/// This is outlined from `process_heap_alloc` so that `process_heap_alloc`
-/// does not need any stack allocations.
 #[inline(never)]
-#[cold]
-extern "C" fn process_heap_init_and_alloc(
-    _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`
+fn process_heap_alloc(
+    _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`,
     flags: u32,
     bytes: usize,
 ) -> *mut c_void {
-    let heap = init_or_get_process_heap();
+    let heap = get_process_heap();
     if core::intrinsics::unlikely(heap.is_null()) {
         return ptr::null_mut();
     }
@@ -122,28 +99,6 @@ extern "C" fn process_heap_init_and_alloc(
     unsafe { HeapAlloc(heap, flags, bytes) }
 }
 
-#[inline(never)]
-fn process_heap_alloc(
-    _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`,
-    flags: u32,
-    bytes: usize,
-) -> *mut c_void {
-    let heap = HEAP.load(Ordering::Relaxed);
-    if core::intrinsics::likely(!heap.is_null()) {
-        // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
-        unsafe { HeapAlloc(heap, flags, bytes) }
-    } else {
-        process_heap_init_and_alloc(MaybeUninit::uninit(), flags, bytes)
-    }
-}
-
-// Get a non-null handle to the default heap of the current process.
-// SAFETY: `HEAP` must have been successfully initialized.
-#[inline]
-unsafe fn get_process_heap() -> c::HANDLE {
-    HEAP.load(Ordering::Acquire)
-}
-
 // Header containing a pointer to the start of an allocated block.
 // SAFETY: Size and alignment must be <= `MIN_ALIGN`.
 #[repr(C)]
@@ -232,9 +187,9 @@ unsafe impl GlobalAlloc for System {
             }
         };
 
-        // SAFETY: because `ptr` has been successfully allocated with this allocator,
-        // `HEAP` must have been successfully initialized.
-        let heap = unsafe { get_process_heap() };
+        // because `ptr` has been successfully allocated with this allocator,
+        // there must be a valid process heap.
+        let heap = get_process_heap();
 
         // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`,
         // `block` is a pointer to the start of an allocated block.
@@ -244,9 +199,9 @@ unsafe impl GlobalAlloc for System {
     #[inline]
     unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
         if layout.align() <= MIN_ALIGN {
-            // SAFETY: because `ptr` has been successfully allocated with this allocator,
-            // `HEAP` must have been successfully initialized.
-            let heap = unsafe { get_process_heap() };
+            // because `ptr` has been successfully allocated with this allocator,
+            // there must be a valid process heap.
+            let heap = get_process_heap();
 
             // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`,
             // `ptr` is a pointer to the start of an allocated block.