|
|
@@ -5,24 +5,56 @@
|
|
|
|
|
|
#include "platform_api_vmcore.h"
|
|
|
|
|
|
+#ifndef BH_ENABLE_TRACE_MMAP
|
|
|
+#define BH_ENABLE_TRACE_MMAP 0
|
|
|
+#endif
|
|
|
+
|
|
|
+#if BH_ENABLE_TRACE_MMAP != 0
|
|
|
+static size_t total_size_mmapped = 0;
|
|
|
+static size_t total_size_munmapped = 0;
|
|
|
+#endif
|
|
|
+
|
|
|
+#define HUGE_PAGE_SIZE (2 * 1024 * 1024)
|
|
|
+
|
|
|
+static inline uintptr_t
|
|
|
+round_up(uintptr_t v, uintptr_t b)
|
|
|
+{
|
|
|
+ uintptr_t m = b - 1;
|
|
|
+ return (v + m) & ~m;
|
|
|
+}
|
|
|
+
|
|
|
+static inline uintptr_t
|
|
|
+round_down(uintptr_t v, uintptr_t b)
|
|
|
+{
|
|
|
+ uintptr_t m = b - 1;
|
|
|
+ return v & ~m;
|
|
|
+}
|
|
|
+
|
|
|
void *
|
|
|
os_mmap(void *hint, size_t size, int prot, int flags)
|
|
|
{
|
|
|
int map_prot = PROT_NONE;
|
|
|
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
|
|
|
uint64 request_size, page_size;
|
|
|
- uint8 *addr;
|
|
|
+ uint8 *addr = MAP_FAILED;
|
|
|
uint32 i;
|
|
|
|
|
|
page_size = (uint64)getpagesize();
|
|
|
request_size = (size + page_size - 1) & ~(page_size - 1);
|
|
|
|
|
|
+#if !defined(__APPLE__) && !defined(__NuttX__)
|
|
|
+ /* huge page isn't supported on MacOS and NuttX */
|
|
|
+ if (request_size >= HUGE_PAGE_SIZE)
|
|
|
+ /* apply one extra huge page */
|
|
|
+ request_size += HUGE_PAGE_SIZE;
|
|
|
+#endif
|
|
|
+
|
|
|
if ((size_t)request_size < size)
|
|
|
/* integer overflow */
|
|
|
return NULL;
|
|
|
|
|
|
if (request_size > 16 * (uint64)UINT32_MAX)
|
|
|
- /* At most 16 G is allowed */
|
|
|
+ /* at most 16 G is allowed */
|
|
|
return NULL;
|
|
|
|
|
|
if (prot & MMAP_PROT_READ)
|
|
|
@@ -80,25 +112,93 @@ os_mmap(void *hint, size_t size, int prot, int flags)
|
|
|
os_munmap(addr, request_size);
|
|
|
}
|
|
|
else {
|
|
|
- /* reset next hint address */
|
|
|
+ /* success, reset next hint address */
|
|
|
hint_addr += request_size;
|
|
|
- return addr;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
hint_addr += BH_MB;
|
|
|
}
|
|
|
}
|
|
|
-#endif
|
|
|
-
|
|
|
- /* try 5 times */
|
|
|
- for (i = 0; i < 5; i++) {
|
|
|
- addr = mmap(hint, request_size, map_prot, map_flags, -1, 0);
|
|
|
- if (addr != MAP_FAILED)
|
|
|
- break;
|
|
|
+#endif /* end of BUILD_TARGET_RISCV64_LP64D || BUILD_TARGET_RISCV64_LP64 */
|
|
|
+
|
|
|
+ /* memory has't been mapped or was mapped failed previously */
|
|
|
+ if (addr == MAP_FAILED) {
|
|
|
+ /* try 5 times */
|
|
|
+ for (i = 0; i < 5; i++) {
|
|
|
+ addr = mmap(hint, request_size, map_prot, map_flags, -1, 0);
|
|
|
+ if (addr != MAP_FAILED)
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if (addr == MAP_FAILED)
|
|
|
+ if (addr == MAP_FAILED) {
|
|
|
+#if BH_ENABLE_TRACE_MMAP != 0
|
|
|
+ os_printf("mmap failed\n");
|
|
|
+#endif
|
|
|
return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+#if BH_ENABLE_TRACE_MMAP != 0
|
|
|
+ total_size_mmapped += request_size;
|
|
|
+ os_printf("mmap return: %p with size: %zu, total_size_mmapped: %zu, "
|
|
|
+ "total_size_munmapped: %zu\n",
|
|
|
+ addr, request_size, total_size_mmapped, total_size_munmapped);
|
|
|
+#endif
|
|
|
+
|
|
|
+#if !defined(__APPLE__) && !defined(__NuttX__)
|
|
|
+ /* huge page isn't supported on MacOS and NuttX */
|
|
|
+ if (request_size > HUGE_PAGE_SIZE) {
|
|
|
+ uintptr_t huge_start, huge_end;
|
|
|
+ size_t prefix_size = 0, suffix_size = HUGE_PAGE_SIZE;
|
|
|
+
|
|
|
+ huge_start = round_up((uintptr_t)addr, HUGE_PAGE_SIZE);
|
|
|
+
|
|
|
+ if (huge_start > (uintptr_t)addr) {
|
|
|
+ prefix_size += huge_start - (uintptr_t)addr;
|
|
|
+ suffix_size -= huge_start - (uintptr_t)addr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* unmap one extra huge page */
|
|
|
+
|
|
|
+ if (prefix_size > 0) {
|
|
|
+ munmap(addr, prefix_size);
|
|
|
+#if BH_ENABLE_TRACE_MMAP != 0
|
|
|
+ total_size_munmapped += prefix_size;
|
|
|
+ os_printf("munmap %p with size: %zu, total_size_mmapped: %zu, "
|
|
|
+ "total_size_munmapped: %zu\n",
|
|
|
+ addr, prefix_size, total_size_mmapped,
|
|
|
+ total_size_munmapped);
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ if (suffix_size > 0) {
|
|
|
+ munmap(addr + request_size - suffix_size, suffix_size);
|
|
|
+#if BH_ENABLE_TRACE_MMAP != 0
|
|
|
+ total_size_munmapped += suffix_size;
|
|
|
+ os_printf("munmap %p with size: %zu, total_size_mmapped: %zu, "
|
|
|
+ "total_size_munmapped: %zu\n",
|
|
|
+ addr + request_size - suffix_size, suffix_size,
|
|
|
+ total_size_mmapped, total_size_munmapped);
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ addr = (uint8 *)huge_start;
|
|
|
+ request_size -= HUGE_PAGE_SIZE;
|
|
|
+
|
|
|
+ huge_end = round_down(huge_start + request_size, HUGE_PAGE_SIZE);
|
|
|
+ if (huge_end > huge_start) {
|
|
|
+ int ret = madvise((void *)huge_start, huge_end - huge_start,
|
|
|
+ MADV_HUGEPAGE);
|
|
|
+ if (ret) {
|
|
|
+#if BH_ENABLE_TRACE_MMAP != 0
|
|
|
+ os_printf(
|
|
|
+ "warning: madvise(%p, %lu) huge page failed, return %d\n",
|
|
|
+ (void *)huge_start, huge_end - huge_start, ret);
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif /* end of __APPLE__ || __NuttX__ */
|
|
|
|
|
|
return addr;
|
|
|
}
|
|
|
@@ -113,7 +213,14 @@ os_munmap(void *addr, size_t size)
|
|
|
if (munmap(addr, request_size)) {
|
|
|
os_printf("os_munmap error addr:%p, size:0x%" PRIx64 ", errno:%d\n",
|
|
|
addr, request_size, errno);
|
|
|
+ return;
|
|
|
}
|
|
|
+#if BH_ENABLE_TRACE_MMAP != 0
|
|
|
+ total_size_munmapped += request_size;
|
|
|
+ os_printf("munmap %p with size: %zu, total_size_mmapped: %zu, "
|
|
|
+ "total_size_munmapped: %zu\n",
|
|
|
+ addr, request_size, total_size_mmapped, total_size_munmapped);
|
|
|
+#endif
|
|
|
}
|
|
|
}
|
|
|
|