Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: make HEAP initializer never inline #120205

Merged
merged 1 commit into from
Jan 27, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions library/std/src/sys/pal/windows/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static HEAP: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
#[inline]
fn init_or_get_process_heap() -> c::HANDLE {
let heap = HEAP.load(Ordering::Relaxed);
if heap.is_null() {
if core::intrinsics::unlikely(heap.is_null()) {
// `HEAP` has not yet been successfully initialized
let heap = unsafe { GetProcessHeap() };
if !heap.is_null() {
Expand All @@ -115,6 +115,16 @@ fn init_or_get_process_heap() -> c::HANDLE {
}
}

#[inline(never)]
fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID {
let heap = init_or_get_process_heap();
if core::intrinsics::unlikely(heap.is_null()) {
return ptr::null_mut();
}
// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
unsafe { HeapAlloc(heap, flags, dwBytes) }
}

// Get a non-null handle to the default heap of the current process.
// SAFETY: `HEAP` must have been successfully initialized.
#[inline]
Expand All @@ -133,25 +143,17 @@ struct Header(*mut u8);
// initialized.
#[inline]
unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 {
let heap = init_or_get_process_heap();
if heap.is_null() {
// Allocation has failed, could not get the current process heap.
return ptr::null_mut();
}

// Allocated memory will be either zeroed or uninitialized.
let flags = if zeroed { HEAP_ZERO_MEMORY } else { 0 };

if layout.align() <= MIN_ALIGN {
// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
// The returned pointer points to the start of an allocated block.
unsafe { HeapAlloc(heap, flags, layout.size()) as *mut u8 }
process_heap_alloc(flags, layout.size()) as *mut u8
} else {
// Allocate extra padding in order to be able to satisfy the alignment.
let total = layout.align() + layout.size();

// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
let ptr = unsafe { HeapAlloc(heap, flags, total) as *mut u8 };
let ptr = process_heap_alloc(flags, total) as *mut u8;
if ptr.is_null() {
// Allocation has failed.
return ptr::null_mut();
Expand Down
Loading