Skip to content

Misleading comment: large_page_size documented as "4MiB on Windows" but GetLargePageMinimum() returns 2 MiB #1338

Description

@GoldJohnKing

Summary

The comment for large_page_size in include/mimalloc/prim.h:26 claims Windows uses 4 MiB large pages. However, mimalloc queries GetLargePageMinimum() at runtime, which returns 2 MiB on every Windows configuration. The "2 or 4 MiB" phrasing is repeated in several other places across the codebase and docs.

The comment in question

Introduced in commit 13e51920 ("fix comments", May 2024):

// include/mimalloc/prim.h:26
size_t  large_page_size;        // 0 if not supported, usually 2MiB (4MiB on Windows)

Why "4 MiB on Windows" is wrong

mimalloc's own code returns 2 MiB on Windows

src/prim/windows/prim.c:108 queries the minimum large-page size at runtime:

if (ok && large_page_size != NULL && pGetLargePageMinimum != NULL) {
  *large_page_size = (*pGetLargePageMinimum)();
}

On every Windows configuration mimalloc targets, GetLargePageMinimum() returns 2 MiB (2,097,152 bytes). The field never holds 4 MiB in practice.

GetLargePageMinimum() has no documented case of returning 4 MiB

Per Raymond Chen's authoritative page-size table [1] and the Microsoft docs [2]:

Windows configuration Large page size
x86-64 (all modern Windows, incl. Windows 11) 2 MiB
x86-32 with PAE (default since Windows XP for DEP/NX) 2 MiB
ARM64 2 MiB
IA-64 (Itanium, discontinued) 16 MiB

Raymond Chen states explicitly [4]:

"In practice, the large page minimum size is 2 MB. … Windows uses PAE even on machines with less than 4GB of physical memory because NX requires PAE."

The 4 MiB figure is the hardware PSE (Page Size Extension) large-page size on non-PAE x86-32 [3], where a page-directory entry with the PS bit set maps 1024 × 4 KB = 4 MB. However:

  • Windows has enabled PAE by default since Windows XP (2001), because PAE is required for Data Execution Prevention (DEP/NX) [10].
  • GetLargePageMinimum() was introduced in Windows Server 2003 — by which time PAE was already the default on x86-32.
  • With PAE enabled, the hardware large-page size drops from 4 MiB to 2 MiB (512 × 4 KB per page table).
  • There is no documented observation of GetLargePageMinimum() ever returning 4,194,304.

The only theoretical path to 4 MiB would be a 32-bit Windows Server 2003 kernel booted with PAE/DEP explicitly disabled (/NOEXECUTE=ALWAYSOFF in boot.ini, loading the non-PAE kernel ntkrnlmp.exe). This is an extraordinarily obscure configuration with no documented confirmation that the API returns 4 MiB even there.

Likely root cause: hardware capability conflated with API return value

The "4 MiB" figure appears to conflate the x86 non-PAE PSE hardware large-page size (4 MB) with what GetLargePageMinimum() actually returns (2 MiB, because Windows runs in PAE/long mode). The comment author may have encountered the 4 MB PSE figure in architecture references and assumed Windows exposes it, when in practice the API has always returned 2 MiB on every supported configuration.

Affected locations

The "2 or 4 MiB" phrasing (or the explicit "4MiB on Windows" claim) appears in multiple places:

File:line Current text
include/mimalloc/prim.h:26 // 0 if not supported, usually 2MiB (4MiB on Windows)
src/os.c:60 // if large OS pages are supported (2 or 4MiB)
include/mimalloc.h:402 // allow use of large (2 or 4 MiB) OS pages
readme.md:384 large OS pages (2 or 4MiB)
doc/mimalloc-doc.h:1226 allow large (2 or 4 MiB) OS pages
doc/mimalloc-doc.h:1673 large OS pages (2 or 4MiB)

Suggested fix

include/mimalloc/prim.h:26 — remove the incorrect "4MiB on Windows" attribution:

// Before
size_t  large_page_size;        // 0 if not supported, usually 2MiB (4MiB on Windows)

// After
size_t  large_page_size;        // 0 if not supported; usually 2MiB

Other locations — replace "2 or 4 MiB" with "2 MiB" (the only value Windows returns in practice):

  • src/os.c:60(2 or 4MiB)(2MiB)
  • include/mimalloc.h:402large (2 or 4 MiB) OS pageslarge (2 MiB) OS pages
  • readme.md:384large OS pages (2 or 4MiB)large OS pages (2MiB)
  • doc/mimalloc-doc.h:1226, doc/mimalloc-doc.h:1673 — same change

Environment

  • mimalloc version: current master (commit 13e51920 and later)
  • Platform: Windows (comment issue; not a runtime bug — runtime queries GetLargePageMinimum() correctly)

References

  1. Raymond Chen, "What are the page sizes used by Windows on various processors?" (2021) — https://devblogs.microsoft.com/oldnewthing/20210510-00/?p=105200
  2. Microsoft Learn, GetLargePageMinimumhttps://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-getlargepageminimum
  3. Wikipedia, "Page Size Extension" — https://en.wikipedia.org/wiki/Page_Size_Extension
  4. Raymond Chen, "Is there a way to change the minimum size for large pages?" (2016) — https://devblogs.microsoft.com/oldnewthing/20160614-00/?p=93665
  5. Microsoft Learn, "Large-Page Support" — https://learn.microsoft.com/en-us/windows/win32/memory/large-page-support
  6. Microsoft Learn, "Physical Address Extension (PAE)" — https://learn.microsoft.com/en-us/windows/win32/memory/physical-address-extension

Note

Some contents of the issue description were drafted with the assistance of GLM-5.2. I noticed that some of the comments did not align with my understanding, so I consulted GLM-5.2 for clarification. I have manually reviewed all of the above content and confirmed that it is consistent with my understanding.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions