| 428 | } |
| 429 | |
| 430 | static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) { |
| 431 | mi_assert_internal(!(large_only && !allow_large)); |
| 432 | static _Atomic(size_t) large_page_try_ok; // = 0; |
| 433 | void* p = NULL; |
| 434 | // Try to allocate large OS pages (2MiB) if allowed or required. |
| 435 | if ((large_only || use_large_os_page(size, try_alignment)) |
| 436 | && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0) { |
| 437 | size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok); |
| 438 | if (!large_only && try_ok > 0) { |
| 439 | // if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive. |
| 440 | // therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times. |
| 441 | mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1); |
| 442 | } |
| 443 | else { |
| 444 | // large OS pages must always reserve and commit. |
| 445 | *is_large = true; |
| 446 | p = mi_win_virtual_allocx(addr, size, try_alignment, flags | MEM_LARGE_PAGES); |
| 447 | if (large_only) return p; |
| 448 | // fall back to non-large page allocation on error (`p == NULL`). |
| 449 | if (p == NULL) { |
| 450 | mi_atomic_store_release(&large_page_try_ok,10UL); // on error, don't try again for the next N allocations |
| 451 | } |
| 452 | } |
| 453 | } |
| 454 | // Fall back to regular page allocation |
| 455 | if (p == NULL) { |
| 456 | *is_large = ((flags&MEM_LARGE_PAGES) != 0); |
| 457 | p = mi_win_virtual_allocx(addr, size, try_alignment, flags); |
| 458 | } |
| 459 | if (p == NULL) { |
| 460 | _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x, large only: %d, allow large: %d)\n", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); |
| 461 | } |
| 462 | return p; |
| 463 | } |
| 464 | |
| 465 | /* ----------------------------------------------------------- |
| 466 | Raw allocation using `sbrk` or `wasm_memory_grow` |
no test coverage detected