win_memmap.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "platform_api_vmcore.h"
  6. #define TRACE_MEMMAP 0
  7. static DWORD
  8. access_to_win32_flags(int prot)
  9. {
  10. DWORD protect = PAGE_NOACCESS;
  11. if (prot & MMAP_PROT_EXEC) {
  12. if (prot & MMAP_PROT_WRITE)
  13. protect = PAGE_EXECUTE_READWRITE;
  14. else
  15. protect = PAGE_EXECUTE_READ;
  16. }
  17. else if (prot & MMAP_PROT_WRITE) {
  18. protect = PAGE_READWRITE;
  19. }
  20. else if (prot & MMAP_PROT_READ) {
  21. protect = PAGE_READONLY;
  22. }
  23. return protect;
  24. }
  25. void *
  26. os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
  27. {
  28. DWORD alloc_type = MEM_RESERVE;
  29. DWORD protect;
  30. size_t request_size, page_size;
  31. void *addr;
  32. page_size = os_getpagesize();
  33. request_size = (size + page_size - 1) & ~(page_size - 1);
  34. if (request_size < size) {
  35. printf("mmap failed: request size overflow due to paging\n");
  36. return NULL;
  37. }
  38. #if WASM_ENABLE_JIT != 0
  39. /**
  40. * Allocate memory at the highest possible address if the
  41. * request size is large, or LLVM JIT might report error:
  42. * IMAGE_REL_AMD64_ADDR32NB relocation requires an ordered
  43. * section layout.
  44. */
  45. if (request_size > 10 * BH_MB)
  46. alloc_type |= MEM_TOP_DOWN;
  47. #endif
  48. protect = access_to_win32_flags(prot);
  49. if (protect != PAGE_NOACCESS) {
  50. alloc_type |= MEM_COMMIT;
  51. }
  52. addr = VirtualAlloc((LPVOID)hint, request_size, alloc_type, protect);
  53. #if TRACE_MEMMAP != 0
  54. printf("Map memory, request_size: %zu, alloc_type: 0x%x, "
  55. "protect: 0x%x, ret: %p\n",
  56. request_size, alloc_type, protect, addr);
  57. #endif
  58. return addr;
  59. }
  60. void
  61. os_munmap(void *addr, size_t size)
  62. {
  63. size_t page_size = os_getpagesize();
  64. size_t request_size = (size + page_size - 1) & ~(page_size - 1);
  65. if (addr) {
  66. if (!VirtualFree(addr, request_size, MEM_DECOMMIT)) {
  67. printf("warning: os_munmap decommit pages failed, "
  68. "addr: %p, request_size: %zu, errno: %d\n",
  69. addr, request_size, errno);
  70. return;
  71. }
  72. if (!VirtualFree(addr, 0, MEM_RELEASE)) {
  73. printf("warning: os_munmap release pages failed, "
  74. "addr: %p, size: %zu, errno:%d\n",
  75. addr, request_size, errno);
  76. }
  77. }
  78. #if TRACE_MEMMAP != 0
  79. printf("Unmap memory, addr: %p, request_size: %zu\n", addr, request_size);
  80. #endif
  81. }
  82. void *
  83. os_mem_commit(void *addr, size_t size, int flags)
  84. {
  85. DWORD protect = access_to_win32_flags(flags);
  86. size_t page_size = os_getpagesize();
  87. size_t request_size = (size + page_size - 1) & ~(page_size - 1);
  88. if (!addr)
  89. return NULL;
  90. #if TRACE_MEMMAP != 0
  91. printf("Commit memory, addr: %p, request_size: %zu, protect: 0x%x\n", addr,
  92. request_size, protect);
  93. #endif
  94. return VirtualAlloc((LPVOID)addr, request_size, MEM_COMMIT, protect);
  95. }
  96. void
  97. os_mem_decommit(void *addr, size_t size)
  98. {
  99. size_t page_size = os_getpagesize();
  100. size_t request_size = (size + page_size - 1) & ~(page_size - 1);
  101. if (!addr)
  102. return;
  103. #if TRACE_MEMMAP != 0
  104. printf("Decommit memory, addr: %p, request_size: %zu\n", addr,
  105. request_size);
  106. #endif
  107. VirtualFree((LPVOID)addr, request_size, MEM_DECOMMIT);
  108. }
  109. int
  110. os_mprotect(void *addr, size_t size, int prot)
  111. {
  112. DWORD protect;
  113. size_t page_size = os_getpagesize();
  114. size_t request_size = (size + page_size - 1) & ~(page_size - 1);
  115. if (!addr)
  116. return 0;
  117. protect = access_to_win32_flags(prot);
  118. #if TRACE_MEMMAP != 0
  119. printf("Mprotect memory, addr: %p, request_size: %zu, protect: 0x%x\n",
  120. addr, request_size, protect);
  121. #endif
  122. return VirtualProtect((LPVOID)addr, request_size, protect, NULL);
  123. }